1 /* 2 * Copyright (c) 1998, 2024, 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 "classfile/symbolTable.hpp" 27 #include "compiler/compilerDirectives.hpp" 28 #include "compiler/compilerOracle.hpp" 29 #include "compiler/methodMatcher.hpp" 30 #include "jvm.h" 31 #include "memory/allocation.inline.hpp" 32 #include "memory/oopFactory.hpp" 33 #include "memory/resourceArea.hpp" 34 #include "oops/klass.hpp" 35 #include "oops/method.inline.hpp" 36 #include "oops/symbol.hpp" 37 #include "opto/phasetype.hpp" 38 #include "opto/traceAutoVectorizationTag.hpp" 39 #include "opto/traceMergeStoresTag.hpp" 40 #include "runtime/globals_extension.hpp" 41 #include "runtime/handles.inline.hpp" 42 #include "runtime/jniHandles.hpp" 43 #include "runtime/os.hpp" 44 #include "utilities/istream.hpp" 45 #include "utilities/parseInteger.hpp" 46 47 // Default compile commands, if defined, are parsed before any of the 48 // explicitly defined compile commands. Thus, explicitly defined compile 49 // commands take precedence over default compile commands. The effect is 50 // as if the default compile commands had been specified at the start of 51 // the command line. 52 static const char* const default_compile_commands[] = { 53 #ifdef ASSERT 54 // In debug builds, impose a (generous) per-compilation memory limit 55 // to catch pathological compilations during testing. The suboption 56 // "crash" will cause the JVM to assert. 57 // 58 // Note: to disable the default limit at the command line, 59 // set a limit of 0 (e.g. -XX:CompileCommand=MemLimit,*.*,0). 60 "MemLimit,*.*,1G~crash", 61 #endif 62 nullptr }; 63 64 static const char* optiontype_names[] = { 65 #define enum_of_types(type, name) name, 66 OPTION_TYPES(enum_of_types) 67 #undef enum_of_types 68 }; 69 70 static const char* optiontype2name(enum OptionType type) { 71 return optiontype_names[static_cast<int>(type)]; 72 } 73 74 static enum OptionType option_types[] = { 75 #define enum_of_options(option, name, ctype) OptionType::ctype, 76 COMPILECOMMAND_OPTIONS(enum_of_options) 77 #undef enum_of_options 78 }; 79 80 static enum OptionType option2type(CompileCommandEnum option) { 81 return option_types[static_cast<int>(option)]; 82 } 83 84 static const char* option_names[] = { 85 #define enum_of_options(option, name, ctype) name, 86 COMPILECOMMAND_OPTIONS(enum_of_options) 87 #undef enum_of_options 88 }; 89 90 static const char* option2name(CompileCommandEnum option) { 91 return option_names[static_cast<int>(option)]; 92 } 93 94 /* Methods to map real type names to OptionType */ 95 template<typename T> 96 static OptionType get_type_for() { 97 return OptionType::Unknown; 98 }; 99 100 template<> OptionType get_type_for<intx>() { 101 return OptionType::Intx; 102 } 103 104 template<> OptionType get_type_for<uintx>() { 105 return OptionType::Uintx; 106 } 107 108 template<> OptionType get_type_for<bool>() { 109 return OptionType::Bool; 110 } 111 112 template<> OptionType get_type_for<ccstr>() { 113 return OptionType::Ccstr; 114 } 115 116 template<> OptionType get_type_for<double>() { 117 return OptionType::Double; 118 } 119 120 class MethodMatcher; 121 class TypedMethodOptionMatcher; 122 123 static TypedMethodOptionMatcher* option_list = nullptr; 124 static bool any_set = false; 125 static bool print_final_memstat_report = false; 126 127 // A filter for quick lookup if an option is set 128 static bool option_filter[static_cast<int>(CompileCommandEnum::Unknown) + 1] = { 0 }; 129 130 static void command_set_in_filter(CompileCommandEnum option) { 131 assert(option != CompileCommandEnum::Unknown, "sanity"); 132 assert(option2type(option) != OptionType::Unknown, "sanity"); 133 134 if ((option != CompileCommandEnum::DontInline) && 135 (option != CompileCommandEnum::Inline) && 136 (option != CompileCommandEnum::Log)) { 137 any_set = true; 138 } 139 option_filter[static_cast<int>(option)] = true; 140 } 141 142 static bool has_command(CompileCommandEnum option) { 143 return option_filter[static_cast<int>(option)]; 144 } 145 146 class TypedMethodOptionMatcher : public MethodMatcher { 147 private: 148 TypedMethodOptionMatcher* _next; 149 CompileCommandEnum _option; 150 public: 151 152 union { 153 bool bool_value; 154 intx intx_value; 155 uintx uintx_value; 156 double double_value; 157 ccstr ccstr_value; 158 } _u; 159 160 TypedMethodOptionMatcher() : MethodMatcher(), 161 _next(nullptr), 162 _option(CompileCommandEnum::Unknown) { 163 memset(&_u, 0, sizeof(_u)); 164 } 165 166 ~TypedMethodOptionMatcher(); 167 static TypedMethodOptionMatcher* parse_method_pattern(char*& line, char* errorbuf, const int buf_size); 168 TypedMethodOptionMatcher* match(const methodHandle &method, CompileCommandEnum option); 169 170 void init(CompileCommandEnum option, TypedMethodOptionMatcher* next) { 171 _next = next; 172 _option = option; 173 } 174 175 void init_matcher(Symbol* class_name, Mode class_mode, 176 Symbol* method_name, Mode method_mode, 177 Symbol* signature) { 178 MethodMatcher::init(class_name, class_mode, method_name, method_mode, signature); 179 } 180 181 void set_next(TypedMethodOptionMatcher* next) {_next = next; } 182 TypedMethodOptionMatcher* next() { return _next; } 183 CompileCommandEnum option() { return _option; } 184 template<typename T> T value(); 185 template<typename T> void set_value(T value); 186 void print(); 187 void print_all(); 188 TypedMethodOptionMatcher* clone(); 189 }; 190 191 // A few templated accessors instead of a full template class. 192 template<> intx TypedMethodOptionMatcher::value<intx>() { 193 return _u.intx_value; 194 } 195 196 template<> uintx TypedMethodOptionMatcher::value<uintx>() { 197 return _u.uintx_value; 198 } 199 200 template<> bool TypedMethodOptionMatcher::value<bool>() { 201 return _u.bool_value; 202 } 203 204 template<> double TypedMethodOptionMatcher::value<double>() { 205 return _u.double_value; 206 } 207 208 template<> ccstr TypedMethodOptionMatcher::value<ccstr>() { 209 return _u.ccstr_value; 210 } 211 212 template<> void TypedMethodOptionMatcher::set_value(intx value) { 213 _u.intx_value = value; 214 } 215 216 template<> void TypedMethodOptionMatcher::set_value(uintx value) { 217 _u.uintx_value = value; 218 } 219 220 template<> void TypedMethodOptionMatcher::set_value(double value) { 221 _u.double_value = value; 222 } 223 224 template<> void TypedMethodOptionMatcher::set_value(bool value) { 225 _u.bool_value = value; 226 } 227 228 template<> void TypedMethodOptionMatcher::set_value(ccstr value) { 229 _u.ccstr_value = (ccstr)os::strdup_check_oom(value); 230 } 231 232 void TypedMethodOptionMatcher::print() { 233 ttyLocker ttyl; 234 print_base(tty); 235 const char* name = option2name(_option); 236 enum OptionType type = option2type(_option); 237 switch (type) { 238 case OptionType::Intx: 239 tty->print_cr(" intx %s = " INTX_FORMAT, name, value<intx>()); 240 break; 241 case OptionType::Uintx: 242 tty->print_cr(" uintx %s = " UINTX_FORMAT, name, value<uintx>()); 243 break; 244 case OptionType::Bool: 245 tty->print_cr(" bool %s = %s", name, value<bool>() ? "true" : "false"); 246 break; 247 case OptionType::Double: 248 tty->print_cr(" double %s = %f", name, value<double>()); 249 break; 250 case OptionType::Ccstr: 251 case OptionType::Ccstrlist: 252 tty->print_cr(" const char* %s = '%s'", name, value<ccstr>()); 253 break; 254 default: 255 ShouldNotReachHere(); 256 } 257 } 258 259 void TypedMethodOptionMatcher::print_all() { 260 print(); 261 if (_next != nullptr) { 262 tty->print(" "); 263 _next->print_all(); 264 } 265 } 266 267 TypedMethodOptionMatcher* TypedMethodOptionMatcher::clone() { 268 TypedMethodOptionMatcher* m = new TypedMethodOptionMatcher(); 269 m->_class_mode = _class_mode; 270 m->_class_name = _class_name; 271 m->_method_mode = _method_mode; 272 m->_method_name = _method_name; 273 m->_signature = _signature; 274 // Need to ref count the symbols 275 if (_class_name != nullptr) { 276 _class_name->increment_refcount(); 277 } 278 if (_method_name != nullptr) { 279 _method_name->increment_refcount(); 280 } 281 if (_signature != nullptr) { 282 _signature->increment_refcount(); 283 } 284 return m; 285 } 286 287 TypedMethodOptionMatcher::~TypedMethodOptionMatcher() { 288 enum OptionType type = option2type(_option); 289 if (type == OptionType::Ccstr || type == OptionType::Ccstrlist) { 290 ccstr v = value<ccstr>(); 291 os::free((void*)v); 292 } 293 } 294 295 TypedMethodOptionMatcher* TypedMethodOptionMatcher::parse_method_pattern(char*& line, char* errorbuf, const int buf_size) { 296 assert(*errorbuf == '\0', "Dont call here with error_msg already set"); 297 const char* error_msg = nullptr; 298 TypedMethodOptionMatcher* tom = new TypedMethodOptionMatcher(); 299 MethodMatcher::parse_method_pattern(line, error_msg, tom); 300 if (error_msg != nullptr) { 301 jio_snprintf(errorbuf, buf_size, error_msg); 302 delete tom; 303 return nullptr; 304 } 305 return tom; 306 } 307 308 TypedMethodOptionMatcher* TypedMethodOptionMatcher::match(const methodHandle& method, CompileCommandEnum option) { 309 TypedMethodOptionMatcher* current = this; 310 while (current != nullptr) { 311 if (current->_option == option) { 312 if (current->matches(method)) { 313 return current; 314 } 315 } 316 current = current->next(); 317 } 318 return nullptr; 319 } 320 321 template<typename T> 322 static void register_command(TypedMethodOptionMatcher* matcher, 323 CompileCommandEnum option, 324 T value) { 325 assert(matcher != option_list, "No circular lists please"); 326 if (option == CompileCommandEnum::Log && !LogCompilation) { 327 tty->print_cr("Warning: +LogCompilation must be enabled in order for individual methods to be logged with "); 328 tty->print_cr(" CompileCommand=log,<method pattern>"); 329 } 330 assert(CompilerOracle::option_matches_type(option, value), "Value must match option type"); 331 332 if (option == CompileCommandEnum::Blackhole && !UnlockExperimentalVMOptions) { 333 warning("Blackhole compile option is experimental and must be enabled via -XX:+UnlockExperimentalVMOptions"); 334 // Delete matcher as we don't keep it 335 delete matcher; 336 return; 337 } 338 339 matcher->init(option, option_list); 340 matcher->set_value<T>(value); 341 option_list = matcher; 342 command_set_in_filter(option); 343 344 if (!CompilerOracle::be_quiet()) { 345 // Print out the successful registration of a compile command 346 ttyLocker ttyl; 347 tty->print("CompileCommand: %s ", option2name(option)); 348 matcher->print(); 349 } 350 351 return; 352 } 353 354 template<typename T> 355 bool CompilerOracle::has_option_value(const methodHandle& method, CompileCommandEnum option, T& value) { 356 assert(option_matches_type(option, value), "Value must match option type"); 357 if (!has_command(option)) { 358 return false; 359 } 360 if (option_list != nullptr) { 361 TypedMethodOptionMatcher* m = option_list->match(method, option); 362 if (m != nullptr) { 363 value = m->value<T>(); 364 return true; 365 } 366 } 367 return false; 368 } 369 370 static bool resolve_inlining_predicate(CompileCommandEnum option, const methodHandle& method) { 371 assert(option == CompileCommandEnum::Inline || option == CompileCommandEnum::DontInline, "Sanity"); 372 bool v1 = false; 373 bool v2 = false; 374 bool has_inline = CompilerOracle::has_option_value(method, CompileCommandEnum::Inline, v1); 375 bool has_dnotinline = CompilerOracle::has_option_value(method, CompileCommandEnum::DontInline, v2); 376 if (has_inline && has_dnotinline) { 377 if (v1 && v2) { 378 // Conflict options detected 379 // Find the last one for that method and return the predicate accordingly 380 // option_list lists options in reverse order. So the first option we find is the last which was specified. 381 CompileCommandEnum last_one = CompileCommandEnum::Unknown; 382 TypedMethodOptionMatcher* current = option_list; 383 while (current != nullptr) { 384 last_one = current->option(); 385 if (last_one == CompileCommandEnum::Inline || last_one == CompileCommandEnum::DontInline) { 386 if (current->matches(method)) { 387 return last_one == option; 388 } 389 } 390 current = current->next(); 391 } 392 ShouldNotReachHere(); 393 return false; 394 } else { 395 // No conflicts 396 return option == CompileCommandEnum::Inline ? v1 : v2; 397 } 398 } else { 399 if (option == CompileCommandEnum::Inline) { 400 return has_inline ? v1 : false; 401 } else { 402 return has_dnotinline ? v2 : false; 403 } 404 } 405 } 406 407 static bool check_predicate(CompileCommandEnum option, const methodHandle& method) { 408 // Special handling for Inline and DontInline since conflict options may be specified 409 if (option == CompileCommandEnum::Inline || option == CompileCommandEnum::DontInline) { 410 return resolve_inlining_predicate(option, method); 411 } 412 413 bool value = false; 414 if (CompilerOracle::has_option_value(method, option, value)) { 415 return value; 416 } 417 return false; 418 } 419 420 bool CompilerOracle::has_any_command_set() { 421 return any_set; 422 } 423 424 // Explicit instantiation for all OptionTypes supported. 425 template bool CompilerOracle::has_option_value<intx>(const methodHandle& method, CompileCommandEnum option, intx& value); 426 template bool CompilerOracle::has_option_value<uintx>(const methodHandle& method, CompileCommandEnum option, uintx& value); 427 template bool CompilerOracle::has_option_value<bool>(const methodHandle& method, CompileCommandEnum option, bool& value); 428 template bool CompilerOracle::has_option_value<ccstr>(const methodHandle& method, CompileCommandEnum option, ccstr& value); 429 template bool CompilerOracle::has_option_value<double>(const methodHandle& method, CompileCommandEnum option, double& value); 430 431 template<typename T> 432 bool CompilerOracle::option_matches_type(CompileCommandEnum option, T& value) { 433 enum OptionType option_type = option2type(option); 434 if (option_type == OptionType::Unknown) { 435 return false; // Can't query options with type Unknown. 436 } 437 if (option_type == OptionType::Ccstrlist) { 438 option_type = OptionType::Ccstr; // CCstrList type options are stored as Ccstr 439 } 440 return (get_type_for<T>() == option_type); 441 } 442 443 template bool CompilerOracle::option_matches_type<intx>(CompileCommandEnum option, intx& value); 444 template bool CompilerOracle::option_matches_type<uintx>(CompileCommandEnum option, uintx& value); 445 template bool CompilerOracle::option_matches_type<bool>(CompileCommandEnum option, bool& value); 446 template bool CompilerOracle::option_matches_type<ccstr>(CompileCommandEnum option, ccstr& value); 447 template bool CompilerOracle::option_matches_type<double>(CompileCommandEnum option, double& value); 448 449 bool CompilerOracle::has_option(const methodHandle& method, CompileCommandEnum option) { 450 bool value = false; 451 has_option_value(method, option, value); 452 return value; 453 } 454 455 bool CompilerOracle::should_exclude(const methodHandle& method) { 456 if (check_predicate(CompileCommandEnum::Exclude, method)) { 457 return true; 458 } 459 if (has_command(CompileCommandEnum::CompileOnly)) { 460 return !check_predicate(CompileCommandEnum::CompileOnly, method); 461 } 462 return false; 463 } 464 465 bool CompilerOracle::should_inline(const methodHandle& method) { 466 return (check_predicate(CompileCommandEnum::Inline, method)); 467 } 468 469 bool CompilerOracle::should_not_inline(const methodHandle& method) { 470 return check_predicate(CompileCommandEnum::DontInline, method) || check_predicate(CompileCommandEnum::Exclude, method); 471 } 472 473 bool CompilerOracle::should_print(const methodHandle& method) { 474 return check_predicate(CompileCommandEnum::Print, method); 475 } 476 477 bool CompilerOracle::should_print_methods() { 478 return has_command(CompileCommandEnum::Print); 479 } 480 481 // Tells whether there are any methods to collect memory statistics for 482 bool CompilerOracle::should_collect_memstat() { 483 return has_command(CompileCommandEnum::MemStat) || has_command(CompileCommandEnum::MemLimit); 484 } 485 486 bool CompilerOracle::should_print_final_memstat_report() { 487 return print_final_memstat_report; 488 } 489 490 bool CompilerOracle::should_log(const methodHandle& method) { 491 if (!LogCompilation) return false; 492 if (!has_command(CompileCommandEnum::Log)) { 493 return true; // by default, log all 494 } 495 return (check_predicate(CompileCommandEnum::Log, method)); 496 } 497 498 bool CompilerOracle::should_break_at(const methodHandle& method) { 499 return check_predicate(CompileCommandEnum::Break, method); 500 } 501 502 void CompilerOracle::tag_blackhole_if_possible(const methodHandle& method) { 503 if (!check_predicate(CompileCommandEnum::Blackhole, method)) { 504 return; 505 } 506 guarantee(UnlockExperimentalVMOptions, "Checked during initial parsing"); 507 if (method->result_type() != T_VOID) { 508 warning("Blackhole compile option only works for methods with void type: %s", 509 method->name_and_sig_as_C_string()); 510 return; 511 } 512 if (!method->is_empty_method()) { 513 warning("Blackhole compile option only works for empty methods: %s", 514 method->name_and_sig_as_C_string()); 515 return; 516 } 517 if (!method->is_static()) { 518 warning("Blackhole compile option only works for static methods: %s", 519 method->name_and_sig_as_C_string()); 520 return; 521 } 522 if (method->intrinsic_id() == vmIntrinsics::_blackhole) { 523 return; 524 } 525 if (method->intrinsic_id() != vmIntrinsics::_none) { 526 warning("Blackhole compile option only works for methods that do not have intrinsic set: %s, %s", 527 method->name_and_sig_as_C_string(), vmIntrinsics::name_at(method->intrinsic_id())); 528 return; 529 } 530 method->set_intrinsic_id(vmIntrinsics::_blackhole); 531 } 532 533 static CompileCommandEnum match_option_name(const char* line, int* bytes_read, char* errorbuf, int bufsize) { 534 assert(ARRAY_SIZE(option_names) == static_cast<int>(CompileCommandEnum::Count), "option_names size mismatch"); 535 536 *bytes_read = 0; 537 char option_buf[256]; 538 int matches = sscanf(line, "%255[a-zA-Z0-9]%n", option_buf, bytes_read); 539 if (matches > 0 && strcasecmp(option_buf, "unknown") != 0) { 540 for (uint i = 0; i < ARRAY_SIZE(option_names); i++) { 541 if (strcasecmp(option_buf, option_names[i]) == 0) { 542 return static_cast<CompileCommandEnum>(i); 543 } 544 } 545 } 546 jio_snprintf(errorbuf, bufsize, "Unrecognized option '%s'", option_buf); 547 return CompileCommandEnum::Unknown; 548 } 549 550 // match exactly and don't mess with errorbuf 551 CompileCommandEnum CompilerOracle::parse_option_name(const char* line) { 552 for (uint i = 0; i < ARRAY_SIZE(option_names); i++) { 553 if (strcasecmp(line, option_names[i]) == 0) { 554 return static_cast<CompileCommandEnum>(i); 555 } 556 } 557 return CompileCommandEnum::Unknown; 558 } 559 560 enum OptionType CompilerOracle::parse_option_type(const char* type_str) { 561 for (uint i = 0; i < ARRAY_SIZE(optiontype_names); i++) { 562 if (strcasecmp(type_str, optiontype_names[i]) == 0) { 563 return static_cast<enum OptionType>(i); 564 } 565 } 566 return OptionType::Unknown; 567 } 568 569 static void print_tip() { // CMH Update info 570 tty->cr(); 571 tty->print_cr("Usage: '-XX:CompileCommand=<option>,<method pattern>' - to set boolean option to true"); 572 tty->print_cr("Usage: '-XX:CompileCommand=<option>,<method pattern>,<value>'"); 573 tty->print_cr("Use: '-XX:CompileCommand=help' for more information and to list all option."); 574 tty->cr(); 575 } 576 577 static void print_option(CompileCommandEnum option, const char* name, enum OptionType type) { 578 if (type != OptionType::Unknown) { 579 tty->print_cr(" %s (%s)", name, optiontype2name(type)); 580 } 581 } 582 583 static void print_commands() { 584 tty->cr(); 585 tty->print_cr("All available options:"); 586 #define enum_of_options(option, name, ctype) print_option(CompileCommandEnum::option, name, OptionType::ctype); 587 COMPILECOMMAND_OPTIONS(enum_of_options) 588 #undef enum_of_options 589 tty->cr(); 590 } 591 592 static void usage() { 593 tty->cr(); 594 tty->print_cr("The CompileCommand option enables the user of the JVM to control specific"); 595 tty->print_cr("behavior of the dynamic compilers."); 596 tty->cr(); 597 tty->print_cr("Compile commands has this general form:"); 598 tty->print_cr("-XX:CompileCommand=<option><method pattern><value>"); 599 tty->print_cr(" Sets <option> to the specified value for methods matching <method pattern>"); 600 tty->print_cr(" All options are typed"); 601 tty->cr(); 602 tty->print_cr("-XX:CompileCommand=<option><method pattern>"); 603 tty->print_cr(" Sets <option> to true for methods matching <method pattern>"); 604 tty->print_cr(" Only applies to boolean options."); 605 tty->cr(); 606 tty->print_cr("-XX:CompileCommand=quiet"); 607 tty->print_cr(" Silence the compile command output"); 608 tty->cr(); 609 tty->print_cr("-XX:CompileCommand=help"); 610 tty->print_cr(" Prints this help text"); 611 tty->cr(); 612 print_commands(); 613 tty->cr(); 614 tty->print_cr("Method patterns has the format:"); 615 tty->print_cr(" package/Class.method()"); 616 tty->cr(); 617 tty->print_cr("For backward compatibility this form is also allowed:"); 618 tty->print_cr(" package.Class::method()"); 619 tty->cr(); 620 tty->print_cr("The signature can be separated by an optional whitespace or comma:"); 621 tty->print_cr(" package/Class.method ()"); 622 tty->cr(); 623 tty->print_cr("The class and method identifier can be used together with leading or"); 624 tty->print_cr("trailing *'s for wildcard matching:"); 625 tty->print_cr(" *ackage/Clas*.*etho*()"); 626 tty->cr(); 627 tty->print_cr("It is possible to use more than one CompileCommand on the command line:"); 628 tty->print_cr(" -XX:CompileCommand=exclude,java/*.* -XX:CompileCommand=log,java*.*"); 629 tty->cr(); 630 tty->print_cr("The CompileCommands can be loaded from a file with the flag"); 631 tty->print_cr("-XX:CompileCommandFile=<file> or be added to the file '.hotspot_compiler'"); 632 tty->print_cr("Use the same format in the file as the argument to the CompileCommand flag."); 633 tty->print_cr("Add one command on each line."); 634 tty->print_cr(" exclude java/*.*"); 635 tty->print_cr(" option java/*.* ReplayInline"); 636 tty->cr(); 637 tty->print_cr("The following commands have conflicting behavior: 'exclude', 'inline', 'dontinline',"); 638 tty->print_cr("and 'compileonly'. There is no priority of commands. Applying (a subset of) these"); 639 tty->print_cr("commands to the same method results in undefined behavior."); 640 tty->cr(); 641 tty->print_cr("The 'exclude' command excludes methods from top-level compilations as well as"); 642 tty->print_cr("from inlining, whereas the 'compileonly' command only excludes methods from"); 643 tty->print_cr("top-level compilations (i.e. they can still be inlined into other compilation units)."); 644 tty->cr(); 645 }; 646 647 static int skip_whitespace(char* &line) { 648 // Skip any leading spaces 649 int whitespace_read = 0; 650 sscanf(line, "%*[ \t]%n", &whitespace_read); 651 line += whitespace_read; 652 return whitespace_read; 653 } 654 655 static void skip_comma(char* &line) { 656 // Skip any leading spaces 657 if (*line == ',') { 658 line++; 659 } 660 } 661 662 static bool parseMemLimit(const char* line, intx& value, int& bytes_read, char* errorbuf, const int buf_size) { 663 // Format: 664 // "<memory size>['~' <suboption>]" 665 // <memory size> can have units, e.g. M 666 // <suboption> one of "crash" "stop", if omitted, "stop" is implied. 667 // 668 // Examples: 669 // -XX:CompileCommand='memlimit,*.*,20m' 670 // -XX:CompileCommand='memlimit,*.*,20m~stop' 671 // -XX:CompileCommand='memlimit,Option::toString,1m~crash' 672 // 673 // The resulting intx carries the size and whether we are to stop or crash: 674 // - neg. value means crash 675 // - pos. value (default) means stop 676 size_t s = 0; 677 char* end; 678 if (!parse_integer<size_t>(line, &end, &s)) { 679 jio_snprintf(errorbuf, buf_size, "MemLimit: invalid value"); 680 return false; 681 } 682 bytes_read = (int)(end - line); 683 684 intx v = (intx)s; 685 if ((*end) != '\0') { 686 if (strncasecmp(end, "~crash", 6) == 0) { 687 v = -v; 688 bytes_read += 6; 689 } else if (strncasecmp(end, "~stop", 5) == 0) { 690 // ok, this is the default 691 bytes_read += 5; 692 } else { 693 jio_snprintf(errorbuf, buf_size, "MemLimit: invalid option"); 694 return false; 695 } 696 } 697 value = v; 698 return true; 699 } 700 701 static bool parseMemStat(const char* line, uintx& value, int& bytes_read, char* errorbuf, const int buf_size) { 702 703 #define IF_ENUM_STRING(S, CMD) \ 704 if (strncasecmp(line, S, strlen(S)) == 0) { \ 705 bytes_read += (int)strlen(S); \ 706 CMD \ 707 return true; \ 708 } 709 710 IF_ENUM_STRING("collect", { 711 value = (uintx)MemStatAction::collect; 712 }); 713 IF_ENUM_STRING("print", { 714 value = (uintx)MemStatAction::print; 715 print_final_memstat_report = true; 716 }); 717 #undef IF_ENUM_STRING 718 719 jio_snprintf(errorbuf, buf_size, "MemStat: invalid option"); 720 721 return false; 722 } 723 724 static void scan_value(enum OptionType type, char* line, int& total_bytes_read, 725 TypedMethodOptionMatcher* matcher, CompileCommandEnum option, char* errorbuf, const int buf_size) { 726 int bytes_read = 0; 727 const char* ccname = option2name(option); 728 const char* type_str = optiontype2name(type); 729 int skipped = skip_whitespace(line); 730 total_bytes_read += skipped; 731 if (type == OptionType::Intx) { 732 intx value; 733 bool success = false; 734 if (option == CompileCommandEnum::MemLimit) { 735 // Special parsing for MemLimit 736 success = parseMemLimit(line, value, bytes_read, errorbuf, buf_size); 737 } else { 738 // Is it a raw number? 739 success = sscanf(line, "" INTX_FORMAT "%n", &value, &bytes_read) == 1; 740 } 741 if (success) { 742 total_bytes_read += bytes_read; 743 line += bytes_read; 744 register_command(matcher, option, value); 745 return; 746 } else { 747 jio_snprintf(errorbuf, buf_size, "Value cannot be read for option '%s' of type '%s'", ccname, type_str); 748 } 749 } else if (type == OptionType::Uintx) { 750 uintx value; 751 bool success = false; 752 if (option == CompileCommandEnum::MemStat) { 753 // Special parsing for MemStat 754 success = parseMemStat(line, value, bytes_read, errorbuf, buf_size); 755 } else { 756 // parse as raw number 757 success = sscanf(line, "" UINTX_FORMAT "%n", &value, &bytes_read) == 1; 758 } 759 if (success) { 760 total_bytes_read += bytes_read; 761 line += bytes_read; 762 register_command(matcher, option, value); 763 } else { 764 jio_snprintf(errorbuf, buf_size, "Value cannot be read for option '%s' of type '%s'", ccname, type_str); 765 } 766 } else if (type == OptionType::Ccstr) { 767 ResourceMark rm; 768 char* value = NEW_RESOURCE_ARRAY(char, strlen(line) + 1); 769 if (sscanf(line, "%255[_a-zA-Z0-9]%n", value, &bytes_read) == 1) { 770 total_bytes_read += bytes_read; 771 line += bytes_read; 772 register_command(matcher, option, (ccstr) value); 773 return; 774 } else { 775 jio_snprintf(errorbuf, buf_size, "Value cannot be read for option '%s' of type '%s'", ccname, type_str); 776 } 777 } else if (type == OptionType::Ccstrlist) { 778 // Accumulates several strings into one. The internal type is ccstr. 779 ResourceMark rm; 780 char* value = NEW_RESOURCE_ARRAY(char, strlen(line) + 1); 781 char* next_value = value; 782 if (sscanf(line, "%255[_a-zA-Z0-9+\\-]%n", next_value, &bytes_read) == 1) { 783 total_bytes_read += bytes_read; 784 line += bytes_read; 785 next_value += bytes_read + 1; 786 char* end_value = next_value - 1; 787 while (sscanf(line, "%*[ \t]%255[_a-zA-Z0-9+\\-]%n", next_value, &bytes_read) == 1) { 788 total_bytes_read += bytes_read; 789 line += bytes_read; 790 *end_value = ' '; // override '\0' 791 next_value += bytes_read; 792 end_value = next_value-1; 793 } 794 795 if (option == CompileCommandEnum::ControlIntrinsic || option == CompileCommandEnum::DisableIntrinsic) { 796 ControlIntrinsicValidator validator(value, (option == CompileCommandEnum::DisableIntrinsic)); 797 798 if (!validator.is_valid()) { 799 jio_snprintf(errorbuf, buf_size, "Unrecognized intrinsic detected in %s: %s", option2name(option), validator.what()); 800 } 801 } 802 #if !defined(PRODUCT) && defined(COMPILER2) 803 else if (option == CompileCommandEnum::TraceAutoVectorization) { 804 TraceAutoVectorizationTagValidator validator(value, true); 805 806 if (!validator.is_valid()) { 807 jio_snprintf(errorbuf, buf_size, "Unrecognized tag name in %s: %s", option2name(option), validator.what()); 808 } 809 } else if (option == CompileCommandEnum::TraceMergeStores) { 810 TraceMergeStores::TagValidator validator(value, true); 811 812 if (!validator.is_valid()) { 813 jio_snprintf(errorbuf, buf_size, "Unrecognized tag name in %s: %s", option2name(option), validator.what()); 814 } 815 } else if (option == CompileCommandEnum::PrintIdealPhase) { 816 PhaseNameValidator validator(value); 817 818 if (!validator.is_valid()) { 819 jio_snprintf(errorbuf, buf_size, "Unrecognized phase name in %s: %s", option2name(option), validator.what()); 820 } 821 } else if (option == CompileCommandEnum::TestOptionList) { 822 // all values are ok 823 } else if (option == CompileCommandEnum::TooManyTrapsAtBCI) { 824 // FIXME 825 } 826 #endif 827 else { 828 assert(false, "Ccstrlist type option missing validator"); 829 } 830 831 register_command(matcher, option, (ccstr) value); 832 return; 833 } else { 834 jio_snprintf(errorbuf, buf_size, "Value cannot be read for option '%s' of type '%s'", ccname, type_str); 835 } 836 } else if (type == OptionType::Bool) { 837 char value[256]; 838 if (*line == '\0') { 839 // Short version of a CompileCommand sets a boolean Option to true 840 // -XXCompileCommand=<Option>,<method pattern> 841 register_command(matcher, option, true); 842 return; 843 } 844 if (sscanf(line, "%255[a-zA-Z]%n", value, &bytes_read) == 1) { 845 if (strcasecmp(value, "true") == 0) { 846 total_bytes_read += bytes_read; 847 line += bytes_read; 848 register_command(matcher, option, true); 849 return; 850 } else if (strcasecmp(value, "false") == 0) { 851 total_bytes_read += bytes_read; 852 line += bytes_read; 853 register_command(matcher, option, false); 854 return; 855 } else { 856 jio_snprintf(errorbuf, buf_size, "Value cannot be read for option '%s' of type '%s'", ccname, type_str); 857 } 858 } else { 859 jio_snprintf(errorbuf, buf_size, "Value cannot be read for option '%s' of type '%s'", ccname, type_str); 860 } 861 } else if (type == OptionType::Double) { 862 char buffer[2][256]; 863 // Decimal separator '.' has been replaced with ' ' or '/' earlier, 864 // so read integer and fraction part of double value separately. 865 if (sscanf(line, "%255[0-9]%*[ /\t]%255[0-9]%n", buffer[0], buffer[1], &bytes_read) == 2) { 866 char value[512] = ""; 867 jio_snprintf(value, sizeof(value), "%s.%s", buffer[0], buffer[1]); 868 total_bytes_read += bytes_read; 869 line += bytes_read; 870 register_command(matcher, option, atof(value)); 871 return; 872 } else { 873 jio_snprintf(errorbuf, buf_size, "Value cannot be read for option '%s' of type '%s'", ccname, type_str); 874 } 875 } else { 876 jio_snprintf(errorbuf, buf_size, "Type '%s' not supported ", type_str); 877 } 878 } 879 880 // Scan next option and value in line, return MethodMatcher object on success, nullptr on failure. 881 // On failure, error_msg contains description for the first error. 882 // For future extensions: set error_msg on first error. 883 static void scan_option_and_value(enum OptionType type, char* line, int& total_bytes_read, 884 TypedMethodOptionMatcher* matcher, 885 char* errorbuf, const int buf_size) { 886 total_bytes_read = 0; 887 int bytes_read = 0; 888 char option_buf[256]; 889 890 // Read option name. 891 if (sscanf(line, "%*[ \t]%255[a-zA-Z0-9]%n", option_buf, &bytes_read) == 1) { 892 line += bytes_read; 893 total_bytes_read += bytes_read; 894 int bytes_read2 = 0; 895 total_bytes_read += skip_whitespace(line); 896 CompileCommandEnum option = match_option_name(option_buf, &bytes_read2, errorbuf, buf_size); 897 if (option == CompileCommandEnum::Unknown) { 898 assert(*errorbuf != '\0', "error must have been set"); 899 return; 900 } 901 enum OptionType optiontype = option2type(option); 902 if (option2type(option) != type) { 903 const char* optiontype_name = optiontype2name(optiontype); 904 const char* type_name = optiontype2name(type); 905 jio_snprintf(errorbuf, buf_size, "Option '%s' with type '%s' doesn't match supplied type '%s'", option_buf, optiontype_name, type_name); 906 return; 907 } 908 scan_value(type, line, total_bytes_read, matcher, option, errorbuf, buf_size); 909 } else { 910 const char* type_str = optiontype2name(type); 911 jio_snprintf(errorbuf, buf_size, "Option name for type '%s' should be alphanumeric ", type_str); 912 } 913 return; 914 } 915 916 void CompilerOracle::print_parse_error(char* error_msg, char* original_line) { 917 assert(*error_msg != '\0', "Must have error_message"); 918 ttyLocker ttyl; 919 tty->print_cr("CompileCommand: An error occurred during parsing"); 920 tty->print_cr("Error: %s", error_msg); 921 tty->print_cr("Line: '%s'", original_line); 922 print_tip(); 923 } 924 925 class LineCopy : StackObj { 926 const char* _copy; 927 public: 928 LineCopy(char* line) { 929 _copy = os::strdup(line, mtInternal); 930 } 931 ~LineCopy() { 932 os::free((void*)_copy); 933 } 934 char* get() { 935 return (char*)_copy; 936 } 937 }; 938 939 bool CompilerOracle::parse_from_line_quietly(char* line) { 940 const bool quiet0 = _quiet; 941 _quiet = true; 942 const bool result = parse_from_line(line); 943 _quiet = quiet0; 944 return result; 945 } 946 947 bool CompilerOracle::parse_from_line(char* line) { 948 if ((line[0] == '\0') || (line[0] == '#')) { 949 return true; 950 } 951 952 LineCopy original(line); 953 int bytes_read; 954 char error_buf[1024] = {0}; 955 956 CompileCommandEnum option = match_option_name(line, &bytes_read, error_buf, sizeof(error_buf)); 957 line += bytes_read; 958 ResourceMark rm; 959 960 if (option == CompileCommandEnum::Unknown) { 961 print_parse_error(error_buf, original.get()); 962 return false; 963 } 964 965 if (option == CompileCommandEnum::Quiet) { 966 _quiet = true; 967 return true; 968 } 969 970 if (option == CompileCommandEnum::Help) { 971 usage(); 972 return true; 973 } 974 975 if (option == CompileCommandEnum::Option) { 976 // Look for trailing options. 977 // 978 // Two types of trailing options are 979 // supported: 980 // 981 // (1) CompileCommand=option,Klass::method,option 982 // (2) CompileCommand=option,Klass::method,type,option,value 983 // 984 // Type (1) is used to enable a boolean option for a method. 985 // 986 // Type (2) is used to support options with a value. Values can have the 987 // the following types: intx, uintx, bool, ccstr, ccstrlist, and double. 988 989 char option_type[256]; // stores option for Type (1) and type of Type (2) 990 skip_comma(line); 991 TypedMethodOptionMatcher* archetype = TypedMethodOptionMatcher::parse_method_pattern(line, error_buf, sizeof(error_buf)); 992 if (archetype == nullptr) { 993 print_parse_error(error_buf, original.get()); 994 return false; 995 } 996 997 skip_whitespace(line); 998 999 // This is unnecessarily complex. Should retire multi-option lines and skip while loop 1000 while (sscanf(line, "%255[a-zA-Z0-9]%n", option_type, &bytes_read) == 1) { 1001 line += bytes_read; 1002 1003 // typed_matcher is used as a blueprint for each option, deleted at the end 1004 TypedMethodOptionMatcher* typed_matcher = archetype->clone(); 1005 enum OptionType type = parse_option_type(option_type); 1006 if (type != OptionType::Unknown) { 1007 // Type (2) option: parse option name and value. 1008 scan_option_and_value(type, line, bytes_read, typed_matcher, error_buf, sizeof(error_buf)); 1009 if (*error_buf != '\0') { 1010 print_parse_error(error_buf, original.get()); 1011 return false; 1012 } 1013 line += bytes_read; 1014 } else { 1015 // Type (1) option - option_type contains the option name -> bool value = true is implied 1016 int bytes_read; 1017 CompileCommandEnum option = match_option_name(option_type, &bytes_read, error_buf, sizeof(error_buf)); 1018 if (option == CompileCommandEnum::Unknown) { 1019 print_parse_error(error_buf, original.get()); 1020 return false; 1021 } 1022 if (option2type(option) == OptionType::Bool) { 1023 register_command(typed_matcher, option, true); 1024 } else { 1025 jio_snprintf(error_buf, sizeof(error_buf), " Missing type '%s' before option '%s'", 1026 optiontype2name(option2type(option)), option2name(option)); 1027 print_parse_error(error_buf, original.get()); 1028 return false; 1029 } 1030 } 1031 assert(typed_matcher != nullptr, "sanity"); 1032 assert(*error_buf == '\0', "No error here"); 1033 skip_whitespace(line); 1034 } // while( 1035 delete archetype; 1036 } else { // not an OptionCommand 1037 // Command has the following form: 1038 // CompileCommand=<option>,<method pattern><value> 1039 // CompileCommand=<option>,<method pattern> (implies option is bool and value is true) 1040 assert(*error_buf == '\0', "Don't call here with error_buf already set"); 1041 enum OptionType type = option2type(option); 1042 int bytes_read = 0; 1043 skip_comma(line); 1044 TypedMethodOptionMatcher* matcher = TypedMethodOptionMatcher::parse_method_pattern(line, error_buf, sizeof(error_buf)); 1045 if (matcher == nullptr) { 1046 print_parse_error(error_buf, original.get()); 1047 return false; 1048 } 1049 skip_whitespace(line); 1050 if (*line == '\0') { 1051 if (option2type(option) == OptionType::Bool) { 1052 // if this is a bool option this implies true 1053 register_command(matcher, option, true); 1054 return true; 1055 } else if (option == CompileCommandEnum::MemStat) { 1056 // MemStat default action is to collect data but to not print 1057 register_command(matcher, option, (uintx)MemStatAction::collect); 1058 return true; 1059 } else { 1060 jio_snprintf(error_buf, sizeof(error_buf), " Option '%s' is not followed by a value", option2name(option)); 1061 print_parse_error(error_buf, original.get()); 1062 return false; 1063 } 1064 } 1065 scan_value(type, line, bytes_read, matcher, option, error_buf, sizeof(error_buf)); 1066 if (*error_buf != '\0') { 1067 print_parse_error(error_buf, original.get()); 1068 return false; 1069 } 1070 assert(matcher != nullptr, "consistency"); 1071 } 1072 return true; 1073 } 1074 1075 static const char* default_cc_file = ".hotspot_compiler"; 1076 1077 static const char* cc_file() { 1078 #ifdef ASSERT 1079 if (CompileCommandFile == nullptr) 1080 return default_cc_file; 1081 #endif 1082 return CompileCommandFile; 1083 } 1084 1085 bool CompilerOracle::has_command_file() { 1086 return cc_file() != nullptr; 1087 } 1088 1089 bool CompilerOracle::_quiet = false; 1090 1091 bool CompilerOracle::parse_from_file() { 1092 assert(has_command_file(), "command file must be specified"); 1093 FILE* stream = os::fopen(cc_file(), "rt"); 1094 if (stream == nullptr) { 1095 return true; 1096 } 1097 1098 FileInput input(stream, /*need_close=*/ true); 1099 return parse_from_input(&input, parse_from_line); 1100 } 1101 1102 bool CompilerOracle::parse_from_input(inputStream::Input* input, 1103 CompilerOracle:: 1104 parse_from_line_fn_t* parse_from_line) { 1105 bool success = true; 1106 for (inputStream in(input); !in.done(); in.next()) { 1107 if (!parse_from_line(in.current_line())) { 1108 success = false; 1109 } 1110 } 1111 return success; 1112 } 1113 1114 bool CompilerOracle::parse_from_string(const char* str, 1115 CompilerOracle:: 1116 parse_from_line_fn_t* parse_from_line) { 1117 MemoryInput input(str, strlen(str)); 1118 return parse_from_input(&input, parse_from_line); 1119 } 1120 1121 bool compilerOracle_init() { 1122 bool success = true; 1123 // Register default compile commands first - any commands specified via CompileCommand will 1124 // supersede these default commands. 1125 for (int i = 0; default_compile_commands[i] != nullptr; i ++) { 1126 char* s = os::strdup(default_compile_commands[i]); 1127 success = CompilerOracle::parse_from_line_quietly(s); 1128 os::free(s); 1129 assert(success, "default compile command \"%s\" failed to parse", default_compile_commands[i]); 1130 } 1131 if (!CompilerOracle::parse_from_string(CompileCommand, CompilerOracle::parse_from_line)) { 1132 success = false; 1133 } 1134 if (!CompilerOracle::parse_from_string(CompileOnly, CompilerOracle::parse_compile_only)) { 1135 success = false; 1136 } 1137 if (CompilerOracle::has_command_file()) { 1138 if (!CompilerOracle::parse_from_file()) { 1139 success = false; 1140 } 1141 } else { 1142 struct stat buf; 1143 if (os::stat(default_cc_file, &buf) == 0) { 1144 warning("%s file is present but has been ignored. " 1145 "Run with -XX:CompileCommandFile=%s to load the file.", 1146 default_cc_file, default_cc_file); 1147 } 1148 } 1149 if (has_command(CompileCommandEnum::Print)) { 1150 if (PrintAssembly) { 1151 warning("CompileCommand and/or %s file contains 'print' commands, but PrintAssembly is also enabled", default_cc_file); 1152 } 1153 } 1154 return success; 1155 } 1156 1157 bool CompilerOracle::parse_compile_only(char* line) { 1158 if (line[0] == '\0') { 1159 return true; 1160 } 1161 ResourceMark rm; 1162 char error_buf[1024] = {0}; 1163 LineCopy original(line); 1164 char* method_pattern; 1165 do { 1166 if (line[0] == '\0') { 1167 break; 1168 } 1169 method_pattern = strtok_r(line, ",", &line); 1170 if (method_pattern != nullptr) { 1171 TypedMethodOptionMatcher* matcher = TypedMethodOptionMatcher::parse_method_pattern(method_pattern, error_buf, sizeof(error_buf)); 1172 if (matcher != nullptr) { 1173 register_command(matcher, CompileCommandEnum::CompileOnly, true); 1174 continue; 1175 } 1176 } 1177 ttyLocker ttyl; 1178 tty->print_cr("CompileOnly: An error occurred during parsing"); 1179 if (*error_buf != '\0') { 1180 tty->print_cr("Error: %s", error_buf); 1181 } 1182 tty->print_cr("Line: '%s'", original.get()); 1183 return false; 1184 } while (method_pattern != nullptr && line != nullptr); 1185 return true; 1186 } 1187 1188 CompileCommandEnum CompilerOracle::string_to_option(const char* name) { 1189 int bytes_read = 0; 1190 char errorbuf[1024] = {0}; 1191 return match_option_name(name, &bytes_read, errorbuf, sizeof(errorbuf)); 1192 }