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