1 /* 2 * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "compiler/compilerOracle.hpp" 27 #include "compiler/methodMatcher.hpp" 28 #include "memory/allocation.inline.hpp" 29 #include "memory/oopFactory.hpp" 30 #include "memory/resourceArea.hpp" 31 #include "oops/klass.hpp" 32 #include "oops/method.hpp" 33 #include "oops/symbol.hpp" 34 #include "runtime/handles.inline.hpp" 35 #include "runtime/jniHandles.hpp" 36 #include "runtime/os.hpp" 37 38 enum OptionType { 39 IntxType, 40 UintxType, 41 BoolType, 42 CcstrType, 43 DoubleType, 44 UnknownType 45 }; 46 47 /* Methods to map real type names to OptionType */ 48 template<typename T> 49 static OptionType get_type_for() { 50 return UnknownType; 51 }; 52 53 template<> OptionType get_type_for<intx>() { 54 return IntxType; 55 } 56 57 template<> OptionType get_type_for<uintx>() { 58 return UintxType; 59 } 60 61 template<> OptionType get_type_for<bool>() { 62 return BoolType; 63 } 64 65 template<> OptionType get_type_for<ccstr>() { 66 return CcstrType; 67 } 68 69 template<> OptionType get_type_for<double>() { 70 return DoubleType; 71 } 72 73 // this must parallel the command_names below 74 enum OracleCommand { 75 UnknownCommand = -1, 76 OracleFirstCommand = 0, 77 BreakCommand = OracleFirstCommand, 78 PrintCommand, 79 ExcludeCommand, 80 InlineCommand, 81 DontInlineCommand, 82 CompileOnlyCommand, 83 LogCommand, 84 OptionCommand, 85 QuietCommand, 86 HelpCommand, 87 OracleCommandCount 88 }; 89 90 // this must parallel the enum OracleCommand 91 static const char * command_names[] = { 92 "break", 93 "print", 94 "exclude", 95 "inline", 96 "dontinline", 97 "compileonly", 98 "log", 99 "option", 100 "quiet", 101 "help" 102 }; 103 104 class MethodMatcher; 105 class TypedMethodOptionMatcher; 106 107 static BasicMatcher* lists[OracleCommandCount] = { 0, }; 108 static TypedMethodOptionMatcher* option_list = NULL; 109 static bool any_set = false; 110 111 class TypedMethodOptionMatcher : public MethodMatcher { 112 private: 113 TypedMethodOptionMatcher* _next; 114 const char* _option; 115 OptionType _type; 116 public: 117 118 union { 119 bool bool_value; 120 intx intx_value; 121 uintx uintx_value; 122 double double_value; 123 ccstr ccstr_value; 124 } _u; 125 126 TypedMethodOptionMatcher() : MethodMatcher(), 127 _next(NULL), 128 _type(UnknownType) { 129 _option = NULL; 130 memset(&_u, 0, sizeof(_u)); 131 } 132 133 static TypedMethodOptionMatcher* parse_method_pattern(char*& line, const char*& error_msg); 134 TypedMethodOptionMatcher* match(methodHandle method, const char* opt, OptionType type); 135 136 void init(const char* opt, OptionType type, TypedMethodOptionMatcher* next) { 137 _next = next; 138 _type = type; 139 _option = os::strdup_check_oom(opt); 140 } 141 142 void set_next(TypedMethodOptionMatcher* next) {_next = next; } 143 TypedMethodOptionMatcher* next() { return _next; } 144 OptionType type() { return _type; } 145 template<typename T> T value(); 146 template<typename T> void set_value(T value); 147 void print(); 148 void print_all(); 149 TypedMethodOptionMatcher* clone(); 150 ~TypedMethodOptionMatcher(); 151 }; 152 153 // A few templated accessors instead of a full template class. 154 template<> intx TypedMethodOptionMatcher::value<intx>() { 155 return _u.intx_value; 156 } 157 158 template<> uintx TypedMethodOptionMatcher::value<uintx>() { 159 return _u.uintx_value; 160 } 161 162 template<> bool TypedMethodOptionMatcher::value<bool>() { 163 return _u.bool_value; 164 } 165 166 template<> double TypedMethodOptionMatcher::value<double>() { 167 return _u.double_value; 168 } 169 170 template<> ccstr TypedMethodOptionMatcher::value<ccstr>() { 171 return _u.ccstr_value; 172 } 173 174 template<> void TypedMethodOptionMatcher::set_value(intx value) { 175 _u.intx_value = value; 176 } 177 178 template<> void TypedMethodOptionMatcher::set_value(uintx value) { 179 _u.uintx_value = value; 180 } 181 182 template<> void TypedMethodOptionMatcher::set_value(double value) { 183 _u.double_value = value; 184 } 185 186 template<> void TypedMethodOptionMatcher::set_value(bool value) { 187 _u.bool_value = value; 188 } 189 190 template<> void TypedMethodOptionMatcher::set_value(ccstr value) { 191 _u.ccstr_value = (const ccstr)os::strdup_check_oom(value); 192 } 193 194 void TypedMethodOptionMatcher::print() { 195 ttyLocker ttyl; 196 print_base(tty); 197 switch (_type) { 198 case IntxType: 199 tty->print_cr(" intx %s = " INTX_FORMAT, _option, value<intx>()); 200 break; 201 case UintxType: 202 tty->print_cr(" uintx %s = " UINTX_FORMAT, _option, value<uintx>()); 203 break; 204 case BoolType: 205 tty->print_cr(" bool %s = %s", _option, value<bool>() ? "true" : "false"); 206 break; 207 case DoubleType: 208 tty->print_cr(" double %s = %f", _option, value<double>()); 209 break; 210 case CcstrType: 211 tty->print_cr(" const char* %s = '%s'", _option, value<ccstr>()); 212 break; 213 default: 214 ShouldNotReachHere(); 215 } 216 } 217 218 void TypedMethodOptionMatcher::print_all() { 219 print(); 220 if (_next != NULL) { 221 tty->print(" "); 222 _next->print_all(); 223 } 224 } 225 226 TypedMethodOptionMatcher* TypedMethodOptionMatcher::clone() { 227 TypedMethodOptionMatcher* m = new TypedMethodOptionMatcher(); 228 m->_class_mode = _class_mode; 229 m->_class_name = _class_name; 230 m->_method_mode = _method_mode; 231 m->_method_name = _method_name; 232 m->_signature = _signature; 233 // Need to ref count the symbols 234 if (_class_name != NULL) { 235 _class_name->increment_refcount(); 236 } 237 if (_method_name != NULL) { 238 _method_name->increment_refcount(); 239 } 240 if (_signature != NULL) { 241 _signature->increment_refcount(); 242 } 243 return m; 244 } 245 246 TypedMethodOptionMatcher::~TypedMethodOptionMatcher() { 247 if (_option != NULL) { 248 os::free((void*)_option); 249 } 250 if (_class_name != NULL) { 251 _class_name->decrement_refcount(); 252 } 253 if (_method_name != NULL) { 254 _method_name->decrement_refcount(); 255 } 256 if (_signature != NULL) { 257 _signature->decrement_refcount(); 258 } 259 } 260 261 TypedMethodOptionMatcher* TypedMethodOptionMatcher::parse_method_pattern(char*& line, const char*& error_msg) { 262 assert(error_msg == NULL, "Dont call here with error_msg already set"); 263 TypedMethodOptionMatcher* tom = new TypedMethodOptionMatcher(); 264 MethodMatcher::parse_method_pattern(line, error_msg, tom); 265 if (error_msg != NULL) { 266 delete tom; 267 return NULL; 268 } 269 return tom; 270 } 271 272 TypedMethodOptionMatcher* TypedMethodOptionMatcher::match(methodHandle method, const char* opt, OptionType type) { 273 TypedMethodOptionMatcher* current = this; 274 while (current != NULL) { 275 // Fastest compare first. 276 if (current->type() == type) { 277 if (strcmp(current->_option, opt) == 0) { 278 if (current->matches(method)) { 279 return current; 280 } 281 } 282 } 283 current = current->next(); 284 } 285 return NULL; 286 } 287 288 template<typename T> 289 static void add_option_string(TypedMethodOptionMatcher* matcher, 290 const char* option, 291 T value) { 292 assert(matcher != option_list, "No circular lists please"); 293 matcher->init(option, get_type_for<T>(), option_list); 294 matcher->set_value<T>(value); 295 option_list = matcher; 296 any_set = true; 297 return; 298 } 299 300 static bool check_predicate(OracleCommand command, methodHandle method) { 301 return ((lists[command] != NULL) && 302 !method.is_null() && 303 lists[command]->match(method)); 304 } 305 306 static void add_predicate(OracleCommand command, BasicMatcher* bm) { 307 assert(command != OptionCommand, "must use add_option_string"); 308 if (command == LogCommand && !LogCompilation && lists[LogCommand] == NULL) { 309 tty->print_cr("Warning: +LogCompilation must be enabled in order for individual methods to be logged."); 310 } 311 bm->set_next(lists[command]); 312 lists[command] = bm; 313 if ((command != DontInlineCommand) && (command != InlineCommand)) { 314 any_set = true; 315 } 316 return; 317 } 318 319 template<typename T> 320 bool CompilerOracle::has_option_value(methodHandle method, const char* option, T& value) { 321 if (option_list != NULL) { 322 TypedMethodOptionMatcher* m = option_list->match(method, option, get_type_for<T>()); 323 if (m != NULL) { 324 value = m->value<T>(); 325 return true; 326 } 327 } 328 return false; 329 } 330 331 bool CompilerOracle::has_any_option() { 332 return any_set; 333 } 334 335 // Explicit instantiation for all OptionTypes supported. 336 template bool CompilerOracle::has_option_value<intx>(methodHandle method, const char* option, intx& value); 337 template bool CompilerOracle::has_option_value<uintx>(methodHandle method, const char* option, uintx& value); 338 template bool CompilerOracle::has_option_value<bool>(methodHandle method, const char* option, bool& value); 339 template bool CompilerOracle::has_option_value<ccstr>(methodHandle method, const char* option, ccstr& value); 340 template bool CompilerOracle::has_option_value<double>(methodHandle method, const char* option, double& value); 341 342 bool CompilerOracle::has_option_string(methodHandle method, const char* option) { 343 bool value = false; 344 has_option_value(method, option, value); 345 return value; 346 } 347 348 bool CompilerOracle::should_exclude(methodHandle method) { 349 if (check_predicate(ExcludeCommand, method)) { 350 return true; 351 } 352 if (lists[CompileOnlyCommand] != NULL) { 353 return !lists[CompileOnlyCommand]->match(method); 354 } 355 return false; 356 } 357 358 bool CompilerOracle::should_inline(methodHandle method) { 359 return (check_predicate(InlineCommand, method)); 360 } 361 362 bool CompilerOracle::should_not_inline(methodHandle method) { 363 return check_predicate(DontInlineCommand, method) || check_predicate(ExcludeCommand, method); 364 } 365 366 bool CompilerOracle::should_print(methodHandle method) { 367 return check_predicate(PrintCommand, method); 368 } 369 370 bool CompilerOracle::should_print_methods() { 371 return lists[PrintCommand] != NULL; 372 } 373 374 bool CompilerOracle::should_log(methodHandle method) { 375 if (!LogCompilation) return false; 376 if (lists[LogCommand] == NULL) return true; // by default, log all 377 return (check_predicate(LogCommand, method)); 378 } 379 380 bool CompilerOracle::should_break_at(methodHandle method) { 381 return check_predicate(BreakCommand, method); 382 } 383 384 static OracleCommand parse_command_name(const char * line, int* bytes_read) { 385 assert(ARRAY_SIZE(command_names) == OracleCommandCount, 386 "command_names size mismatch"); 387 388 *bytes_read = 0; 389 char command[33]; 390 int result = sscanf(line, "%32[a-z]%n", command, bytes_read); 391 for (uint i = 0; i < ARRAY_SIZE(command_names); i++) { 392 if (strcmp(command, command_names[i]) == 0) { 393 return (OracleCommand)i; 394 } 395 } 396 return UnknownCommand; 397 } 398 399 static void usage() { 400 tty->cr(); 401 tty->print_cr("The CompileCommand option enables the user of the JVM to control specific"); 402 tty->print_cr("behavior of the dynamic compilers. Many commands require a pattern that defines"); 403 tty->print_cr("the set of methods the command shall be applied to. The CompileCommand"); 404 tty->print_cr("option provides the following commands:"); 405 tty->cr(); 406 tty->print_cr(" break,<pattern> - debug breakpoint in compiler and in generated code"); 407 tty->print_cr(" print,<pattern> - print assembly"); 408 tty->print_cr(" exclude,<pattern> - don't compile or inline"); 409 tty->print_cr(" inline,<pattern> - always inline"); 410 tty->print_cr(" dontinline,<pattern> - don't inline"); 411 tty->print_cr(" compileonly,<pattern> - compile only"); 412 tty->print_cr(" log,<pattern> - log compilation"); 413 tty->print_cr(" option,<pattern>,<option type>,<option name>,<value>"); 414 tty->print_cr(" - set value of custom option"); 415 tty->print_cr(" option,<pattern>,<bool option name>"); 416 tty->print_cr(" - shorthand for setting boolean flag"); 417 tty->print_cr(" quiet - silence the compile command output"); 418 tty->print_cr(" help - print this text"); 419 tty->cr(); 420 tty->print_cr("The preferred format for the method matching pattern is:"); 421 tty->print_cr(" package/Class.method()"); 422 tty->cr(); 423 tty->print_cr("For backward compatibility this form is also allowed:"); 424 tty->print_cr(" package.Class::method()"); 425 tty->cr(); 426 tty->print_cr("The signature can be separated by an optional whitespace or comma:"); 427 tty->print_cr(" package/Class.method ()"); 428 tty->cr(); 429 tty->print_cr("The class and method identifier can be used together with leading or"); 430 tty->print_cr("trailing *'s for a small amount of wildcarding:"); 431 tty->print_cr(" *ackage/Clas*.*etho*()"); 432 tty->cr(); 433 tty->print_cr("It is possible to use more than one CompileCommand on the command line:"); 434 tty->print_cr(" -XX:CompileCommand=exclude,java/*.* -XX:CompileCommand=log,java*.*"); 435 tty->cr(); 436 tty->print_cr("The CompileCommands can be loaded from a file with the flag"); 437 tty->print_cr("-XX:CompileCommandFile=<file> or be added to the file '.hotspot_compiler'"); 438 tty->print_cr("Use the same format in the file as the argument to the CompileCommand flag."); 439 tty->print_cr("Add one command on each line."); 440 tty->print_cr(" exclude java/*.*"); 441 tty->print_cr(" option java/*.* ReplayInline"); 442 tty->cr(); 443 tty->print_cr("The following commands have conflicting behavior: 'exclude', 'inline', 'dontinline',"); 444 tty->print_cr("and 'compileonly'. There is no priority of commands. Applying (a subset of) these"); 445 tty->print_cr("commands to the same method results in undefined behavior."); 446 tty->cr(); 447 }; 448 449 // Scan next flag and value in line, return MethodMatcher object on success, NULL on failure. 450 // On failure, error_msg contains description for the first error. 451 // For future extensions: set error_msg on first error. 452 static void scan_flag_and_value(const char* type, const char* line, int& total_bytes_read, 453 TypedMethodOptionMatcher* matcher, 454 char* errorbuf, const int buf_size) { 455 total_bytes_read = 0; 456 int bytes_read = 0; 457 char flag[256]; 458 459 // Read flag name. 460 if (sscanf(line, "%*[ \t]%255[a-zA-Z0-9]%n", flag, &bytes_read) == 1) { 461 line += bytes_read; 462 total_bytes_read += bytes_read; 463 464 // Read value. 465 if (strcmp(type, "intx") == 0) { 466 intx value; 467 if (sscanf(line, "%*[ \t]" INTX_FORMAT "%n", &value, &bytes_read) == 1) { 468 total_bytes_read += bytes_read; 469 add_option_string(matcher, flag, value); 470 return; 471 } else { 472 jio_snprintf(errorbuf, buf_size, " Value cannot be read for flag %s of type %s ", flag, type); 473 } 474 } else if (strcmp(type, "uintx") == 0) { 475 uintx value; 476 if (sscanf(line, "%*[ \t]" UINTX_FORMAT "%n", &value, &bytes_read) == 1) { 477 total_bytes_read += bytes_read; 478 add_option_string(matcher, flag, value); 479 return; 480 } else { 481 jio_snprintf(errorbuf, buf_size, " Value cannot be read for flag %s of type %s", flag, type); 482 } 483 } else if (strcmp(type, "ccstr") == 0) { 484 ResourceMark rm; 485 char* value = NEW_RESOURCE_ARRAY(char, strlen(line) + 1); 486 if (sscanf(line, "%*[ \t]%255[_a-zA-Z0-9]%n", value, &bytes_read) == 1) { 487 total_bytes_read += bytes_read; 488 add_option_string(matcher, flag, (ccstr)value); 489 return; 490 } else { 491 jio_snprintf(errorbuf, buf_size, " Value cannot be read for flag %s of type %s", flag, type); 492 } 493 } else if (strcmp(type, "ccstrlist") == 0) { 494 // Accumulates several strings into one. The internal type is ccstr. 495 ResourceMark rm; 496 char* value = NEW_RESOURCE_ARRAY(char, strlen(line) + 1); 497 char* next_value = value; 498 if (sscanf(line, "%*[ \t]%255[_a-zA-Z0-9]%n", next_value, &bytes_read) == 1) { 499 total_bytes_read += bytes_read; 500 line += bytes_read; 501 next_value += bytes_read; 502 char* end_value = next_value-1; 503 while (sscanf(line, "%*[ \t]%255[_a-zA-Z0-9]%n", next_value, &bytes_read) == 1) { 504 total_bytes_read += bytes_read; 505 line += bytes_read; 506 *end_value = ' '; // override '\0' 507 next_value += bytes_read; 508 end_value = next_value-1; 509 } 510 add_option_string(matcher, flag, (ccstr)value); 511 return; 512 } else { 513 jio_snprintf(errorbuf, buf_size, " Value cannot be read for flag %s of type %s", flag, type); 514 } 515 } else if (strcmp(type, "bool") == 0) { 516 char value[256]; 517 if (sscanf(line, "%*[ \t]%255[a-zA-Z]%n", value, &bytes_read) == 1) { 518 if (strcmp(value, "true") == 0) { 519 total_bytes_read += bytes_read; 520 add_option_string(matcher, flag, true); 521 return; 522 } else if (strcmp(value, "false") == 0) { 523 total_bytes_read += bytes_read; 524 add_option_string(matcher, flag, false); 525 return; 526 } else { 527 jio_snprintf(errorbuf, buf_size, " Value cannot be read for flag %s of type %s", flag, type); 528 } 529 } else { 530 jio_snprintf(errorbuf, buf_size, " Value cannot be read for flag %s of type %s", flag, type); 531 } 532 } else if (strcmp(type, "double") == 0) { 533 char buffer[2][256]; 534 // Decimal separator '.' has been replaced with ' ' or '/' earlier, 535 // so read integer and fraction part of double value separately. 536 if (sscanf(line, "%*[ \t]%255[0-9]%*[ /\t]%255[0-9]%n", buffer[0], buffer[1], &bytes_read) == 2) { 537 char value[512] = ""; 538 jio_snprintf(value, sizeof(value), "%s.%s", buffer[0], buffer[1]); 539 total_bytes_read += bytes_read; 540 add_option_string(matcher, flag, atof(value)); 541 return; 542 } else { 543 jio_snprintf(errorbuf, buf_size, " Value cannot be read for flag %s of type %s", flag, type); 544 } 545 } else { 546 jio_snprintf(errorbuf, buf_size, " Type %s not supported ", type); 547 } 548 } else { 549 jio_snprintf(errorbuf, buf_size, " Flag name for type %s should be alphanumeric ", type); 550 } 551 return; 552 } 553 554 int skip_whitespace(char* line) { 555 // Skip any leading spaces 556 int whitespace_read = 0; 557 sscanf(line, "%*[ \t]%n", &whitespace_read); 558 return whitespace_read; 559 } 560 561 void CompilerOracle::print_parse_error(const char*& error_msg, char* original_line) { 562 assert(error_msg != NULL, "Must have error_message"); 563 564 ttyLocker ttyl; 565 tty->print_cr("CompileCommand: An error occurred during parsing"); 566 tty->print_cr("Line: %s", original_line); 567 tty->print_cr("Error: %s", error_msg); 568 CompilerOracle::print_tip(); 569 } 570 571 void CompilerOracle::parse_from_line(char* line) { 572 if (line[0] == '\0') return; 573 if (line[0] == '#') return; 574 575 char* original_line = line; 576 int bytes_read; 577 OracleCommand command = parse_command_name(line, &bytes_read); 578 line += bytes_read; 579 ResourceMark rm; 580 581 if (command == UnknownCommand) { 582 ttyLocker ttyl; 583 tty->print_cr("CompileCommand: unrecognized command"); 584 tty->print_cr(" \"%s\"", original_line); 585 CompilerOracle::print_tip(); 586 return; 587 } 588 589 if (command == QuietCommand) { 590 _quiet = true; 591 return; 592 } 593 594 if (command == HelpCommand) { 595 usage(); 596 return; 597 } 598 599 const char* error_msg = NULL; 600 if (command == OptionCommand) { 601 // Look for trailing options. 602 // 603 // Two types of trailing options are 604 // supported: 605 // 606 // (1) CompileCommand=option,Klass::method,flag 607 // (2) CompileCommand=option,Klass::method,type,flag,value 608 // 609 // Type (1) is used to enable a boolean flag for a method. 610 // 611 // Type (2) is used to support options with a value. Values can have the 612 // the following types: intx, uintx, bool, ccstr, ccstrlist, and double. 613 // 614 // For future extensions: extend scan_flag_and_value() 615 616 char option[256]; // stores flag for Type (1) and type of Type (2) 617 line++; // skip the ',' 618 TypedMethodOptionMatcher* archetype = TypedMethodOptionMatcher::parse_method_pattern(line, error_msg); 619 if (archetype == NULL) { 620 assert(error_msg != NULL, "Must have error_message"); 621 print_parse_error(error_msg, original_line); 622 return; 623 } 624 625 line += skip_whitespace(line); 626 627 // This is unnecessarily complex. Should retire multi-option lines and skip while loop 628 while (sscanf(line, "%255[a-zA-Z0-9]%n", option, &bytes_read) == 1) { 629 line += bytes_read; 630 631 // typed_matcher is used as a blueprint for each option, deleted at the end 632 TypedMethodOptionMatcher* typed_matcher = archetype->clone(); 633 if (strcmp(option, "intx") == 0 634 || strcmp(option, "uintx") == 0 635 || strcmp(option, "bool") == 0 636 || strcmp(option, "ccstr") == 0 637 || strcmp(option, "ccstrlist") == 0 638 || strcmp(option, "double") == 0 639 ) { 640 char errorbuf[1024] = {0}; 641 // Type (2) option: parse flag name and value. 642 scan_flag_and_value(option, line, bytes_read, typed_matcher, errorbuf, sizeof(errorbuf)); 643 if (*errorbuf != '\0') { 644 error_msg = errorbuf; 645 print_parse_error(error_msg, original_line); 646 return; 647 } 648 line += bytes_read; 649 } else { 650 // Type (1) option 651 add_option_string(typed_matcher, option, true); 652 } 653 if (typed_matcher != NULL && !_quiet) { 654 // Print out the last match added 655 assert(error_msg == NULL, "No error here"); 656 ttyLocker ttyl; 657 tty->print("CompileCommand: %s ", command_names[command]); 658 typed_matcher->print(); 659 } 660 line += skip_whitespace(line); 661 } // while( 662 delete archetype; 663 } else { // not an OptionCommand) 664 assert(error_msg == NULL, "Don't call here with error_msg already set"); 665 666 BasicMatcher* matcher = BasicMatcher::parse_method_pattern(line, error_msg); 667 if (error_msg != NULL) { 668 assert(matcher == NULL, "consistency"); 669 print_parse_error(error_msg, original_line); 670 return; 671 } 672 673 add_predicate(command, matcher); 674 if (!_quiet) { 675 ttyLocker ttyl; 676 tty->print("CompileCommand: %s ", command_names[command]); 677 matcher->print(tty); 678 tty->cr(); 679 } 680 } 681 } 682 683 void CompilerOracle::print_tip() { 684 tty->cr(); 685 tty->print_cr("Usage: '-XX:CompileCommand=command,\"package/Class.method()\"'"); 686 tty->print_cr("Use: '-XX:CompileCommand=help' for more information."); 687 tty->cr(); 688 } 689 690 static const char* default_cc_file = ".hotspot_compiler"; 691 692 static const char* cc_file() { 693 #ifdef ASSERT 694 if (CompileCommandFile == NULL) 695 return default_cc_file; 696 #endif 697 return CompileCommandFile; 698 } 699 700 bool CompilerOracle::has_command_file() { 701 return cc_file() != NULL; 702 } 703 704 bool CompilerOracle::_quiet = false; 705 706 void CompilerOracle::parse_from_file() { 707 assert(has_command_file(), "command file must be specified"); 708 FILE* stream = fopen(cc_file(), "rt"); 709 if (stream == NULL) return; 710 711 char token[1024]; 712 int pos = 0; 713 int c = getc(stream); 714 while(c != EOF && pos < (int)(sizeof(token)-1)) { 715 if (c == '\n') { 716 token[pos++] = '\0'; 717 parse_from_line(token); 718 pos = 0; 719 } else { 720 token[pos++] = c; 721 } 722 c = getc(stream); 723 } 724 token[pos++] = '\0'; 725 parse_from_line(token); 726 727 fclose(stream); 728 } 729 730 void CompilerOracle::parse_from_string(const char* str, void (*parse_line)(char*)) { 731 char token[1024]; 732 int pos = 0; 733 const char* sp = str; 734 int c = *sp++; 735 while (c != '\0' && pos < (int)(sizeof(token)-1)) { 736 if (c == '\n') { 737 token[pos++] = '\0'; 738 parse_line(token); 739 pos = 0; 740 } else { 741 token[pos++] = c; 742 } 743 c = *sp++; 744 } 745 token[pos++] = '\0'; 746 parse_line(token); 747 } 748 749 void CompilerOracle::append_comment_to_file(const char* message) { 750 assert(has_command_file(), "command file must be specified"); 751 fileStream stream(fopen(cc_file(), "at")); 752 stream.print("# "); 753 for (int index = 0; message[index] != '\0'; index++) { 754 stream.put(message[index]); 755 if (message[index] == '\n') stream.print("# "); 756 } 757 stream.cr(); 758 } 759 760 void CompilerOracle::append_exclude_to_file(methodHandle method) { 761 assert(has_command_file(), "command file must be specified"); 762 fileStream stream(fopen(cc_file(), "at")); 763 stream.print("exclude "); 764 method->method_holder()->name()->print_symbol_on(&stream); 765 stream.print("."); 766 method->name()->print_symbol_on(&stream); 767 method->signature()->print_symbol_on(&stream); 768 stream.cr(); 769 stream.cr(); 770 } 771 772 773 void compilerOracle_init() { 774 CompilerOracle::parse_from_string(CompileCommand, CompilerOracle::parse_from_line); 775 CompilerOracle::parse_from_string(CompileOnly, CompilerOracle::parse_compile_only); 776 if (CompilerOracle::has_command_file()) { 777 CompilerOracle::parse_from_file(); 778 } else { 779 struct stat buf; 780 if (os::stat(default_cc_file, &buf) == 0) { 781 warning("%s file is present but has been ignored. " 782 "Run with -XX:CompileCommandFile=%s to load the file.", 783 default_cc_file, default_cc_file); 784 } 785 } 786 if (lists[PrintCommand] != NULL) { 787 if (PrintAssembly) { 788 warning("CompileCommand and/or %s file contains 'print' commands, but PrintAssembly is also enabled", default_cc_file); 789 } else if (FLAG_IS_DEFAULT(DebugNonSafepoints)) { 790 warning("printing of assembly code is enabled; turning on DebugNonSafepoints to gain additional output"); 791 DebugNonSafepoints = true; 792 } 793 } 794 } 795 796 797 void CompilerOracle::parse_compile_only(char * line) { 798 int i; 799 char name[1024]; 800 const char* className = NULL; 801 const char* methodName = NULL; 802 803 bool have_colon = (strstr(line, "::") != NULL); 804 char method_sep = have_colon ? ':' : '.'; 805 806 if (Verbose) { 807 tty->print_cr("%s", line); 808 } 809 810 ResourceMark rm; 811 while (*line != '\0') { 812 MethodMatcher::Mode c_match = MethodMatcher::Exact; 813 MethodMatcher::Mode m_match = MethodMatcher::Exact; 814 815 for (i = 0; 816 i < 1024 && *line != '\0' && *line != method_sep && *line != ',' && !isspace(*line); 817 line++, i++) { 818 name[i] = *line; 819 if (name[i] == '.') name[i] = '/'; // package prefix uses '/' 820 } 821 822 if (i > 0) { 823 char* newName = NEW_RESOURCE_ARRAY( char, i + 1); 824 if (newName == NULL) 825 return; 826 strncpy(newName, name, i); 827 newName[i] = '\0'; 828 829 if (className == NULL) { 830 className = newName; 831 c_match = MethodMatcher::Prefix; 832 } else { 833 methodName = newName; 834 } 835 } 836 837 if (*line == method_sep) { 838 if (className == NULL) { 839 className = ""; 840 c_match = MethodMatcher::Any; 841 } else { 842 // foo/bar.blah is an exact match on foo/bar, bar.blah is a suffix match on bar 843 if (strchr(className, '/') != NULL) { 844 c_match = MethodMatcher::Exact; 845 } else { 846 c_match = MethodMatcher::Suffix; 847 } 848 } 849 } else { 850 // got foo or foo/bar 851 if (className == NULL) { 852 ShouldNotReachHere(); 853 } else { 854 // got foo or foo/bar 855 if (strchr(className, '/') != NULL) { 856 c_match = MethodMatcher::Prefix; 857 } else if (className[0] == '\0') { 858 c_match = MethodMatcher::Any; 859 } else { 860 c_match = MethodMatcher::Substring; 861 } 862 } 863 } 864 865 // each directive is terminated by , or NUL or . followed by NUL 866 if (*line == ',' || *line == '\0' || (line[0] == '.' && line[1] == '\0')) { 867 if (methodName == NULL) { 868 methodName = ""; 869 if (*line != method_sep) { 870 m_match = MethodMatcher::Any; 871 } 872 } 873 874 EXCEPTION_MARK; 875 Symbol* c_name = SymbolTable::new_symbol(className, CHECK); 876 Symbol* m_name = SymbolTable::new_symbol(methodName, CHECK); 877 Symbol* signature = NULL; 878 879 BasicMatcher* bm = new BasicMatcher(); 880 bm->init(c_name, c_match, m_name, m_match, signature); 881 add_predicate(CompileOnlyCommand, bm); 882 if (PrintVMOptions) { 883 tty->print("CompileOnly: compileonly "); 884 lists[CompileOnlyCommand]->print_all(tty); 885 } 886 887 className = NULL; 888 methodName = NULL; 889 } 890 891 line = *line == '\0' ? line : line + 1; 892 } 893 }