1 /*
   2  * Copyright (c) 1998, 2014, 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 "ci/ciMethod.hpp"
  27 #include "ci/ciUtilities.hpp"
  28 #include "compiler/abstractCompiler.hpp"
  29 #include "compiler/compilerDirectives.hpp"
  30 #include "compiler/compilerOracle.hpp"
  31 
  32 CompilerDirectives::CompilerDirectives() :_match(NULL), _next(NULL), _ref_count(0) {
  33   _c1_store = new DirectiveSet(this);
  34   _c2_store = new DirectiveSet(this);
  35 };
  36 
  37 CompilerDirectives::~CompilerDirectives() {
  38   if (_c1_store != NULL) {
  39     delete _c1_store;
  40   }
  41   if (_c2_store != NULL) {
  42     delete _c2_store;
  43   }
  44 
  45   // remove all linked method matchers
  46   BasicMatcher* tmp = _match;
  47   while (tmp != NULL) {
  48     BasicMatcher* next = tmp->next();
  49     delete tmp;
  50     tmp = next;
  51   }
  52 }
  53 
  54 void CompilerDirectives::print(outputStream* st) {
  55   assert(DirectivesStack_lock->owned_by_self(), "");
  56   if (_match != NULL) {
  57     st->cr();
  58     st->print("Directive:");
  59     if (is_default_directive()) {
  60       st->print_cr(" (default)");
  61     } else {
  62       st->cr();
  63     }
  64     st->print(" matching: ");
  65     _match->print(st);
  66     BasicMatcher* tmp = _match->next();
  67     while (tmp != NULL) {
  68       st->print(", ");
  69       tmp->print(st);
  70       tmp = tmp->next();
  71     }
  72     st->cr();
  73   } else {
  74     assert(0, "There should always be a match");
  75   }
  76 
  77   if (_c1_store != NULL) {
  78     st->print_cr(" c1 directives:");
  79     _c1_store->print(st);
  80   }
  81   if (_c2_store != NULL) {
  82     st->cr();
  83     st->print_cr(" c2 directives:");
  84     _c2_store->print(st);
  85   }
  86   //---
  87 }
  88 
  89 void CompilerDirectives::finalize(outputStream* st) {
  90   if (_c1_store != NULL) {
  91     _c1_store->finalize(st);
  92   }
  93   if (_c2_store != NULL) {
  94     _c2_store->finalize(st);
  95   }
  96 }
  97 
  98 void DirectiveSet::finalize(outputStream* st) {
  99   // Check LogOption and warn
 100   if (LogOption && !LogCompilation) {
 101     st->print_cr("Warning:  +LogCompilation must be set to enable compilation logging from directives");
 102   }
 103 
 104   // if any flag has been modified - set directive as enabled
 105   // unless it already has been explicitly set.
 106   if (!_modified[EnableIndex]) {
 107     if (_inlinematchers != NULL) {
 108       EnableOption = true;
 109       return;
 110     }
 111     int i;
 112     for (i = 0; i < number_of_flags; i++) {
 113       if (_modified[i]) {
 114         EnableOption = true;
 115         return;
 116       }
 117     }
 118   }
 119 }
 120 
 121 CompilerDirectives* CompilerDirectives::next() {
 122   return _next;
 123 }
 124 
 125 bool CompilerDirectives::match(methodHandle method) {
 126   if (is_default_directive()) {
 127     return true;
 128   }
 129   if (method == NULL) {
 130     return false;
 131   }
 132   if (_match->match(method)) {
 133     return true;
 134   }
 135   return false;
 136 }
 137 
 138 bool CompilerDirectives::add_match(char* str, const char*& error_msg) {
 139   BasicMatcher* bm = BasicMatcher::parse_method_pattern(str, error_msg);
 140   if (bm == NULL) {
 141     assert(error_msg != NULL, "Must have error message");
 142     return false;
 143   } else {
 144     bm->set_next(_match);
 145     _match = bm;
 146     return true;
 147   }
 148 }
 149 
 150 void CompilerDirectives::inc_refcount() {
 151   assert(DirectivesStack_lock->owned_by_self(), "");
 152   _ref_count++;
 153 }
 154 
 155 void CompilerDirectives::dec_refcount() {
 156   assert(DirectivesStack_lock->owned_by_self(), "");
 157   _ref_count--;
 158 }
 159 
 160 int CompilerDirectives::refcount() {
 161   assert(DirectivesStack_lock->owned_by_self(), "");
 162   return _ref_count;
 163 }
 164 
 165 DirectiveSet* CompilerDirectives::get_for(AbstractCompiler *comp) {
 166   assert(DirectivesStack_lock->owned_by_self(), "");
 167   inc_refcount(); // The compiling thread is responsible to decrement this when finished.
 168   if (comp == NULL) { // Xint
 169     return _c1_store;
 170   } else if (comp->is_c2()) {
 171     return _c2_store;
 172   } else if (comp->is_c1()) {
 173     return _c1_store;
 174   } else if (comp->is_shark()) {
 175     return NULL;
 176   } else if (comp->is_jvmci()) {
 177     return NULL;
 178   }
 179   ShouldNotReachHere();
 180   return NULL;
 181 }
 182 
 183 // In the list of disabled intrinsics, the ID of the disabled intrinsics can separated:
 184 // - by ',' (if -XX:DisableIntrinsic is used once when invoking the VM) or
 185 // - by '\n' (if -XX:DisableIntrinsic is used multiple times when invoking the VM) or
 186 // - by ' ' (if DisableIntrinsic is used on a per-method level, e.g., with CompileCommand).
 187 //
 188 // To simplify the processing of the list, the canonicalize_disableintrinsic() method
 189 // returns a new copy of the list in which '\n' and ' ' is replaced with ','.
 190 ccstrlist DirectiveSet::canonicalize_disableintrinsic(ccstrlist option_value) {
 191   char* canonicalized_list = NEW_C_HEAP_ARRAY(char, strlen(option_value) + 1, mtCompiler);
 192   int i = 0;
 193   char current;
 194   while ((current = option_value[i]) != '\0') {
 195     if (current == '\n' || current == ' ') {
 196       canonicalized_list[i] = ',';
 197     } else {
 198       canonicalized_list[i] = current;
 199     }
 200     i++;
 201   }
 202   canonicalized_list[i] = '\0';
 203   return canonicalized_list;
 204 }
 205 
 206 DirectiveSet::DirectiveSet(CompilerDirectives* d) :_inlinematchers(NULL), _directive(d) {
 207 #define init_defaults_definition(name, type, dvalue, compiler) this->name##Option = dvalue;
 208   compilerdirectives_common_flags(init_defaults_definition)
 209   compilerdirectives_c2_flags(init_defaults_definition)
 210   compilerdirectives_c1_flags(init_defaults_definition)
 211   memset(_modified, 0, sizeof _modified);
 212 
 213   // Canonicalize DisableIntrinsic to contain only ',' as a separator.
 214   this->DisableIntrinsicOption = canonicalize_disableintrinsic(DisableIntrinsic);
 215 }
 216 
 217 DirectiveSet::~DirectiveSet() {
 218   // remove all linked methodmatchers
 219   InlineMatcher* tmp = _inlinematchers;
 220   while (tmp != NULL) {
 221     InlineMatcher* next = tmp->next();
 222     delete tmp;
 223     tmp = next;
 224   }
 225 
 226   // When constructed, DirectiveSet canonicalizes the DisableIntrinsic flag
 227   // into a new string. Therefore, that string is deallocated when
 228   // the DirectiveSet is destroyed.
 229   assert(this->DisableIntrinsicOption != NULL, "");
 230   FREE_C_HEAP_ARRAY(char, (void *)this->DisableIntrinsicOption);
 231 }
 232 
 233 // Backward compatibility for CompileCommands
 234 // Breaks the abstraction and causes lots of extra complexity
 235 // - if some option is changed we need to copy directiveset since it no longer can be shared
 236 // - Need to free copy after use
 237 // - Requires a modified bit so we don't overwrite options that is set by directives
 238 
 239 DirectiveSet* DirectiveSet::compilecommand_compatibility_init(methodHandle method) {
 240   // Early bail out - checking all options is expensive - we rely on them not being used
 241   // Only set a flag if it has not been modified and value changes.
 242   // Only copy set if a flag needs to be set
 243   if (!CompilerDirectivesIgnoreCompileCommandsOption && CompilerOracle::has_any_option()) {
 244     DirectiveSet* set = DirectiveSet::clone(this);
 245 
 246     bool changed = false; // Track if we actually change anything
 247 
 248     // All CompileCommands are not equal so this gets a bit verbose
 249     // When CompileCommands have been refactored less clutter will remain.
 250     if (CompilerOracle::should_break_at(method)) {
 251       if (!_modified[BreakAtCompileIndex]) {
 252         set->BreakAtCompileOption = true;
 253         changed = true;
 254       }
 255       if (!_modified[BreakAtExecuteIndex]) {
 256         set->BreakAtExecuteOption = true;
 257         changed = true;
 258       }
 259     }
 260     if (!_modified[LogIndex]) {
 261       bool log = CompilerOracle::should_log(method);
 262       if (log != set->LogOption) {
 263         set->LogOption = log;
 264         changed = true;
 265       }
 266     }
 267 
 268     if (CompilerOracle::should_print(method)) {
 269       if (!_modified[PrintAssemblyIndex]) {
 270         set->PrintAssemblyOption = true;
 271         changed = true;
 272       }
 273     }
 274     // Exclude as in should not compile == Enabled
 275     if (CompilerOracle::should_exclude(method)) {
 276       if (!_modified[ExcludeIndex]) {
 277         set->ExcludeOption = true;
 278         changed = true;
 279       }
 280     }
 281 
 282     // inline and dontinline (including exclude) are implemented in the directiveset accessors
 283 #define init_default_cc(name, type, dvalue, cc_flag) { type v; if (!_modified[name##Index] && CompilerOracle::has_option_value(method, #cc_flag, v) && v != this->name##Option) { set->name##Option = v; changed = true;} }
 284     compilerdirectives_common_flags(init_default_cc)
 285     compilerdirectives_c2_flags(init_default_cc)
 286     compilerdirectives_c1_flags(init_default_cc)
 287 
 288     // Canonicalize DisableIntrinsic to contain only ',' as a separator.
 289     ccstrlist option_value;
 290     if (!_modified[DisableIntrinsicIndex] &&
 291         CompilerOracle::has_option_value(method, "DisableIntrinsic", option_value)) {
 292       set->DisableIntrinsicOption = canonicalize_disableintrinsic(option_value);
 293     }
 294 
 295 
 296     if (!changed) {
 297       // We didn't actually update anything, discard.
 298       delete set;
 299     } else {
 300       // We are returning a (parentless) copy. The originals parent don't need to account for this.
 301       DirectivesStack::release(this);
 302       return set;
 303     }
 304   }
 305   // Nothing changed
 306   return this;
 307 }
 308 
 309 CompilerDirectives* DirectiveSet::directive() {
 310   assert(_directive != NULL, "Must have been initialized");
 311   return _directive;
 312 }
 313 
 314 bool DirectiveSet::matches_inline(methodHandle method, int inline_action) {
 315   if (_inlinematchers != NULL) {
 316     if (_inlinematchers->match(method, inline_action)) {
 317       return true;
 318     }
 319   }
 320   return false;
 321 }
 322 
 323 bool DirectiveSet::should_inline(ciMethod* inlinee) {
 324   inlinee->check_is_loaded();
 325   VM_ENTRY_MARK;
 326   methodHandle mh(THREAD, inlinee->get_Method());
 327 
 328   if (_inlinematchers != NULL) {
 329     return matches_inline(mh, InlineMatcher::force_inline);
 330   }
 331   if (!CompilerDirectivesIgnoreCompileCommandsOption) {
 332     return CompilerOracle::should_inline(mh);
 333   }
 334   return false;
 335 }
 336 
 337 bool DirectiveSet::should_not_inline(ciMethod* inlinee) {
 338   inlinee->check_is_loaded();
 339   VM_ENTRY_MARK;
 340   methodHandle mh(THREAD, inlinee->get_Method());
 341 
 342   if (_inlinematchers != NULL) {
 343     return matches_inline(mh, InlineMatcher::dont_inline);
 344   }
 345   if (!CompilerDirectivesIgnoreCompileCommandsOption) {
 346     return CompilerOracle::should_not_inline(mh);
 347   }
 348   return false;
 349 }
 350 
 351 bool DirectiveSet::parse_and_add_inline(char* str, const char*& error_msg) {
 352   InlineMatcher* m = InlineMatcher::parse_inline_pattern(str, error_msg);
 353   if (m != NULL) {
 354     // add matcher last in chain - the order is significant
 355     append_inline(m);
 356     return true;
 357   } else {
 358     assert(error_msg != NULL, "Error message must be set");
 359     return false;
 360   }
 361 }
 362 
 363 void DirectiveSet::append_inline(InlineMatcher* m) {
 364   if (_inlinematchers == NULL) {
 365     _inlinematchers = m;
 366     return;
 367   }
 368   InlineMatcher* tmp = _inlinematchers;
 369   while (tmp->next() != NULL) {
 370     tmp = tmp->next();
 371   }
 372   tmp->set_next(m);
 373 }
 374 
 375 void DirectiveSet::print_inline(outputStream* st) {
 376   if (_inlinematchers == NULL) {
 377     st->print_cr("  inline: -");
 378   } else {
 379     st->print("  inline: ");
 380     _inlinematchers->print(st);
 381     InlineMatcher* tmp = _inlinematchers->next();
 382     while (tmp != NULL) {
 383       st->print(", ");
 384       tmp->print(st);
 385       tmp = tmp->next();
 386     }
 387     st->cr();
 388   }
 389 }
 390 
 391 bool DirectiveSet::is_intrinsic_disabled(methodHandle method) {
 392   vmIntrinsics::ID id = method->intrinsic_id();
 393   assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
 394 
 395   ResourceMark rm;
 396 
 397   // Create a copy of the string that contains the list of disabled
 398   // intrinsics. The copy is created because the string
 399   // will be modified by strtok(). Then, the list is tokenized with
 400   // ',' as a separator.
 401   size_t length = strlen(DisableIntrinsicOption);
 402   char* local_list = NEW_RESOURCE_ARRAY(char, length + 1);
 403   strncpy(local_list, DisableIntrinsicOption, length + 1);
 404 
 405   char* token = strtok(local_list, ",");
 406   while (token != NULL) {
 407     if (strcmp(token, vmIntrinsics::name_at(id)) == 0) {
 408       return true;
 409     } else {
 410       token = strtok(NULL, ",");
 411     }
 412   }
 413 
 414   return false;
 415 }
 416 
 417 DirectiveSet* DirectiveSet::clone(DirectiveSet const* src) {
 418   DirectiveSet* set = new DirectiveSet(NULL);
 419   memcpy(set->_modified, src->_modified, sizeof(src->_modified));
 420 
 421   InlineMatcher* tmp = src->_inlinematchers;
 422   while (tmp != NULL) {
 423     set->append_inline(tmp->clone());
 424     tmp = tmp->next();
 425   }
 426 
 427   #define copy_members_definition(name, type, dvalue, cc_flag) set->name##Option = src->name##Option;
 428     compilerdirectives_common_flags(copy_members_definition)
 429     compilerdirectives_c2_flags(copy_members_definition)
 430     compilerdirectives_c1_flags(copy_members_definition)
 431 
 432   // Create a local copy of the DisableIntrinsicOption.
 433   assert(src->DisableIntrinsicOption != NULL, "");
 434   size_t len = strlen(src->DisableIntrinsicOption) + 1;
 435   char* s = NEW_C_HEAP_ARRAY(char, len, mtCompiler);
 436   strncpy(s, src->DisableIntrinsicOption, len);
 437   assert(s[len-1] == '\0', "");
 438   set->DisableIntrinsicOption = s;
 439   return set;
 440 }
 441 
 442 // Create a new dirstack and push a default directive
 443 void DirectivesStack::init() {
 444   CompilerDirectives* _default_directives = new CompilerDirectives();
 445   char str[] = "*.*";
 446   const char* error_msg = NULL;
 447   _default_directives->add_match(str, error_msg);
 448 #ifdef COMPILER1
 449   _default_directives->_c1_store->EnableOption = true;
 450 #endif
 451 #ifdef COMPILER2
 452   _default_directives->_c2_store->EnableOption = true;
 453 #endif
 454   assert(error_msg == NULL, "Must succeed.");
 455   push(_default_directives);
 456 }
 457 
 458 DirectiveSet* DirectivesStack::getDefaultDirective(AbstractCompiler* comp) {
 459   MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag);
 460 
 461   assert(_bottom != NULL, "Must never be empty");
 462   return _bottom->get_for(comp);
 463 }
 464 
 465 void DirectivesStack::push(CompilerDirectives* directive) {
 466   MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag);
 467 
 468   directive->inc_refcount();
 469   if (_top == NULL) {
 470     assert(_bottom == NULL, "There can only be one default directive");
 471     _bottom = directive; // default directive, can never be removed.
 472   }
 473 
 474   directive->set_next(_top);
 475   _top = directive;
 476   _depth++;
 477 }
 478 
 479 void DirectivesStack::pop() {
 480   MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag);
 481   pop_inner();
 482 }
 483 
 484 void DirectivesStack::pop_inner() {
 485   assert(DirectivesStack_lock->owned_by_self(), "");
 486 
 487   if (_top->next() == NULL) {
 488     return; // Do nothing - don't allow an empty stack
 489   }
 490   CompilerDirectives* tmp = _top;
 491   _top = _top->next();
 492   _depth--;
 493 
 494   DirectivesStack::release(tmp);
 495 }
 496 
 497 bool DirectivesStack::check_capacity(int request_size, outputStream* st) {
 498   if ((request_size + _depth) > CompilerDirectivesLimit) {
 499     st->print_cr("Could not add %i more directives. Currently %i/%i directives.", request_size, _depth, CompilerDirectivesLimit);
 500     return false;
 501   }
 502   return true;
 503 }
 504 
 505 void DirectivesStack::clear() {
 506   // holding the lock during the whole operation ensuring consistent result
 507   MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag);
 508   while (_top->next() != NULL) {
 509     pop_inner();
 510   }
 511 }
 512 
 513 void DirectivesStack::print(outputStream* st) {
 514   MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag);
 515   CompilerDirectives* tmp = _top;
 516   while (tmp != NULL) {
 517     tmp->print(st);
 518     tmp = tmp->next();
 519     st->cr();
 520   }
 521 }
 522 
 523 void DirectivesStack::release(DirectiveSet* set) {
 524   MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag);
 525   if (set->is_exclusive_copy()) {
 526     // Old CompilecCmmands forced us to create an exclusive copy
 527     delete set;
 528   } else {
 529     assert(set->directive() != NULL, "");
 530     release(set->directive());
 531   }
 532 }
 533 
 534 
 535 void DirectivesStack::release(CompilerDirectives* dir) {
 536   assert(DirectivesStack_lock->owned_by_self(), "");
 537   dir->dec_refcount();
 538   if (dir->refcount() == 0) {
 539     delete dir;
 540   }
 541 }
 542 
 543 DirectiveSet* DirectivesStack::getMatchingDirective(methodHandle method, AbstractCompiler *comp) {
 544   assert(_depth > 0, "Must never be empty");
 545 
 546   DirectiveSet* match = NULL;
 547   {
 548     MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag);
 549 
 550     CompilerDirectives* dir = _top;
 551     assert(dir != NULL, "Must be initialized");
 552 
 553     while (dir != NULL) {
 554       if (dir->is_default_directive() || dir->match(method)) {
 555         match = dir->get_for(comp);
 556         if (match == NULL) {
 557           // temporary workaround for compilers without directives.
 558           if (dir->is_default_directive()) {
 559             // default dir is always enabled
 560             // match c1 store - it contains all common flags even if C1 is unavailable
 561             match = dir->_c1_store;
 562             break;
 563           }
 564         } else {
 565           if (match->EnableOption) {
 566             // The directiveSet for this compile is also enabled -> success
 567             break;
 568           }
 569         }
 570       }
 571       dir = dir->next();
 572     }
 573   }
 574 
 575   guarantee(match != NULL, "There should always be a default directive that matches");
 576   // Check for legacy compile commands update, without DirectivesStack_lock
 577   return match->compilecommand_compatibility_init(method);
 578 }