hotspot/src/share/vm/compiler/compilerDirectives.cpp
changeset 33451 0712796e4039
child 33479 2f62e0833ea2
equal deleted inserted replaced
33450:08222df07d0d 33451:0712796e4039
       
     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() {
       
    90   if (_c1_store != NULL) {
       
    91     _c1_store->finalize();
       
    92   }
       
    93   if (_c2_store != NULL) {
       
    94     _c2_store->finalize();
       
    95   }
       
    96 }
       
    97 
       
    98 void DirectiveSet::finalize() {
       
    99   // if any flag has been modified - set directive as enabled
       
   100   // unless it already has been explicitly set.
       
   101   if (!_modified[EnableIndex]) {
       
   102     if (_inlinematchers != NULL) {
       
   103       EnableOption = true;
       
   104       return;
       
   105     }
       
   106     int i;
       
   107     for (i = 0; i < number_of_flags; i++) {
       
   108       if (_modified[i]) {
       
   109         EnableOption = true;
       
   110         return;
       
   111       }
       
   112     }
       
   113   }
       
   114 }
       
   115 
       
   116 CompilerDirectives* CompilerDirectives::next() {
       
   117   return _next;
       
   118 }
       
   119 
       
   120 bool CompilerDirectives::match(methodHandle method) {
       
   121   if (is_default_directive()) {
       
   122     return true;
       
   123   }
       
   124   if (method == NULL) {
       
   125     return false;
       
   126   }
       
   127   if (_match->match(method)) {
       
   128     return true;
       
   129   }
       
   130   return false;
       
   131 }
       
   132 
       
   133 bool CompilerDirectives::add_match(char* str, const char*& error_msg) {
       
   134   BasicMatcher* bm = BasicMatcher::parse_method_pattern(str, error_msg);
       
   135   if (bm == NULL) {
       
   136     assert(error_msg != NULL, "Must have error message");
       
   137     return false;
       
   138   } else {
       
   139     bm->set_next(_match);
       
   140     _match = bm;
       
   141     return true;
       
   142   }
       
   143 }
       
   144 
       
   145 void CompilerDirectives::inc_refcount() {
       
   146   assert(DirectivesStack_lock->owned_by_self(), "");
       
   147   _ref_count++;
       
   148 }
       
   149 
       
   150 void CompilerDirectives::dec_refcount() {
       
   151   assert(DirectivesStack_lock->owned_by_self(), "");
       
   152   _ref_count--;
       
   153 }
       
   154 
       
   155 int CompilerDirectives::refcount() {
       
   156   assert(DirectivesStack_lock->owned_by_self(), "");
       
   157   return _ref_count;
       
   158 }
       
   159 
       
   160 DirectiveSet* CompilerDirectives::get_for(AbstractCompiler *comp) {
       
   161   assert(DirectivesStack_lock->owned_by_self(), "");
       
   162   inc_refcount(); // The compiling thread is responsible to decrement this when finished.
       
   163   if (comp == NULL) { // Xint
       
   164     return _c1_store;
       
   165   } else if (comp->is_c2()) {
       
   166     return _c2_store;
       
   167   } else if (comp->is_c1()) {
       
   168     return _c1_store;
       
   169   } else if (comp->is_shark()) {
       
   170     return NULL;
       
   171   } else if (comp->is_jvmci()) {
       
   172     return NULL;
       
   173   }
       
   174   ShouldNotReachHere();
       
   175   return NULL;
       
   176 }
       
   177 
       
   178 DirectiveSet::DirectiveSet(CompilerDirectives* d) :_inlinematchers(NULL), _directive(d) {
       
   179 #define init_defaults_definition(name, type, dvalue, compiler) this->name##Option = dvalue;
       
   180   compilerdirectives_common_flags(init_defaults_definition)
       
   181   compilerdirectives_c2_flags(init_defaults_definition)
       
   182   compilerdirectives_c1_flags(init_defaults_definition)
       
   183   memset(_modified, 0, sizeof _modified);
       
   184 }
       
   185 
       
   186 DirectiveSet::~DirectiveSet() {
       
   187   // remove all linked methodmatchers
       
   188   InlineMatcher* tmp = _inlinematchers;
       
   189   while (tmp != NULL) {
       
   190     InlineMatcher* next = tmp->next();
       
   191     delete tmp;
       
   192     tmp = next;
       
   193   }
       
   194 
       
   195   // Free if modified, otherwise it just points to the global vm flag value
       
   196   // or to the Compile command option
       
   197   if (_modified[DisableIntrinsicIndex]) {
       
   198     assert(this->DisableIntrinsicOption != NULL, "");
       
   199     FREE_C_HEAP_ARRAY(char, (void *)this->DisableIntrinsicOption);
       
   200   }
       
   201 }
       
   202 
       
   203 // Backward compatibility for CompileCommands
       
   204 // Breaks the abstraction and causes lots of extra complexity
       
   205 // - if some option is changed we need to copy directiveset since it no longer can be shared
       
   206 // - Need to free copy after use
       
   207 // - Requires a modified bit so we don't overwrite options that is set by directives
       
   208 
       
   209 DirectiveSet* DirectiveSet::compilecommand_compatibility_init(methodHandle method) {
       
   210   // Early bail out - checking all options is expensive - we rely on them not being used
       
   211   // Only set a flag if it has not been modified and value changes.
       
   212   // Only copy set if a flag needs to be set
       
   213   if (!CompilerDirectivesIgnoreCompileCommandsOption && CompilerOracle::has_any_option()) {
       
   214     DirectiveSet* set = DirectiveSet::clone(this);
       
   215 
       
   216     bool changed = false; // Track if we actually change anything
       
   217 
       
   218     // All CompileCommands are not equal so this gets a bit verbose
       
   219     // When CompileCommands have been refactored less clutter will remain.
       
   220     if (CompilerOracle::should_break_at(method)) {
       
   221       if (!_modified[BreakAtCompileIndex]) {
       
   222         set->BreakAtCompileOption = true;
       
   223         changed = true;
       
   224       }
       
   225       if (!_modified[BreakAtExecuteIndex]) {
       
   226         set->BreakAtExecuteOption = true;
       
   227         changed = true;
       
   228       }
       
   229     }
       
   230     if (CompilerOracle::should_log(method)) {
       
   231       if (!_modified[LogIndex]) {
       
   232         set->LogOption = true;
       
   233         changed = true;
       
   234       }
       
   235     }
       
   236     if (CompilerOracle::should_print(method)) {
       
   237       if (!_modified[PrintAssemblyIndex]) {
       
   238         set->PrintAssemblyOption = true;
       
   239         changed = true;
       
   240       }
       
   241     }
       
   242     // Exclude as in should not compile == Enabled
       
   243     if (CompilerOracle::should_exclude(method)) {
       
   244       if (!_modified[ExcludeIndex]) {
       
   245         set->ExcludeOption = true;
       
   246         changed = true;
       
   247       }
       
   248     }
       
   249 
       
   250     // inline and dontinline (including exclude) are implemented in the directiveset accessors
       
   251 #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;} }
       
   252     compilerdirectives_common_flags(init_default_cc)
       
   253     compilerdirectives_c2_flags(init_default_cc)
       
   254     compilerdirectives_c1_flags(init_default_cc)
       
   255 
       
   256     if (!changed) {
       
   257       // We didn't actually update anything, discard.
       
   258       delete set;
       
   259     } else {
       
   260       // We are returning a (parentless) copy. The originals parent don't need to account for this.
       
   261       DirectivesStack::release(this);
       
   262       return set;
       
   263     }
       
   264   }
       
   265   // Nothing changed
       
   266   return this;
       
   267 }
       
   268 
       
   269 CompilerDirectives* DirectiveSet::directive() {
       
   270   assert(_directive != NULL, "Must have been initialized");
       
   271   return _directive;
       
   272 }
       
   273 
       
   274 bool DirectiveSet::matches_inline(methodHandle method, int inline_action) {
       
   275   if (_inlinematchers != NULL) {
       
   276     if (_inlinematchers->match(method, InlineMatcher::force_inline)) {
       
   277       return true;
       
   278     }
       
   279   }
       
   280   return false;
       
   281 }
       
   282 
       
   283 bool DirectiveSet::should_inline(ciMethod* inlinee) {
       
   284   inlinee->check_is_loaded();
       
   285   VM_ENTRY_MARK;
       
   286   methodHandle mh(THREAD, inlinee->get_Method());
       
   287 
       
   288   if (matches_inline(mh, InlineMatcher::force_inline)) {
       
   289     return true;
       
   290   }
       
   291   if (!CompilerDirectivesIgnoreCompileCommandsOption && CompilerOracle::should_inline(mh)) {
       
   292     return true;
       
   293   }
       
   294   return false;
       
   295 }
       
   296 
       
   297 bool DirectiveSet::should_not_inline(ciMethod* inlinee) {
       
   298   inlinee->check_is_loaded();
       
   299   VM_ENTRY_MARK;
       
   300   methodHandle mh(THREAD, inlinee->get_Method());
       
   301 
       
   302   if (matches_inline(mh, InlineMatcher::dont_inline)) {
       
   303     return true;
       
   304   }
       
   305   if (!CompilerDirectivesIgnoreCompileCommandsOption && CompilerOracle::should_not_inline(mh)) {
       
   306     return true;
       
   307   }
       
   308   return false;
       
   309 }
       
   310 
       
   311 bool DirectiveSet::parse_and_add_inline(char* str, const char*& error_msg) {
       
   312   InlineMatcher* m = InlineMatcher::parse_inline_pattern(str, error_msg);
       
   313   if (m != NULL) {
       
   314     // add matcher last in chain - the order is significant
       
   315     append_inline(m);
       
   316     return true;
       
   317   } else {
       
   318     assert(error_msg != NULL, "Error message must be set");
       
   319     return false;
       
   320   }
       
   321 }
       
   322 
       
   323 void DirectiveSet::append_inline(InlineMatcher* m) {
       
   324   if (_inlinematchers == NULL) {
       
   325     _inlinematchers = m;
       
   326     return;
       
   327   }
       
   328   InlineMatcher* tmp = _inlinematchers;
       
   329   while (tmp->next() != NULL) {
       
   330     tmp = tmp->next();
       
   331   }
       
   332   tmp->set_next(m);
       
   333 }
       
   334 
       
   335 void DirectiveSet::print_inline(outputStream* st) {
       
   336   if (_inlinematchers == NULL) {
       
   337     st->print_cr("  inline: -");
       
   338   } else {
       
   339     st->print("  inline: ");
       
   340     _inlinematchers->print(st);
       
   341     InlineMatcher* tmp = _inlinematchers->next();
       
   342     while (tmp != NULL) {
       
   343       st->print(", ");
       
   344       tmp->print(st);
       
   345       tmp = tmp->next();
       
   346     }
       
   347     st->cr();
       
   348   }
       
   349 }
       
   350 
       
   351 bool DirectiveSet::is_intrinsic_disabled(methodHandle method) {
       
   352   vmIntrinsics::ID id = method->intrinsic_id();
       
   353   assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
       
   354 
       
   355   ccstr disable_intr =  DisableIntrinsicOption;
       
   356   return ((disable_intr != '\0') && strstr(disable_intr, vmIntrinsics::name_at(id)) != NULL);
       
   357 }
       
   358 
       
   359 DirectiveSet* DirectiveSet::clone(DirectiveSet const* src) {
       
   360   DirectiveSet* set = new DirectiveSet(NULL);
       
   361   memcpy(set->_modified, src->_modified, sizeof(src->_modified));
       
   362 
       
   363   InlineMatcher* tmp = src->_inlinematchers;
       
   364   while (tmp != NULL) {
       
   365     set->append_inline(tmp->clone());
       
   366     tmp = tmp->next();
       
   367   }
       
   368 
       
   369   #define copy_members_definition(name, type, dvalue, cc_flag) set->name##Option = src->name##Option;
       
   370     compilerdirectives_common_flags(copy_members_definition)
       
   371     compilerdirectives_c2_flags(copy_members_definition)
       
   372     compilerdirectives_c1_flags(copy_members_definition)
       
   373 
       
   374   // Must duplicate ccstr option if it was modified, otherwise it is global.
       
   375   if (src->_modified[DisableIntrinsicIndex]) {
       
   376     assert(src->DisableIntrinsicOption != NULL, "");
       
   377     size_t len = strlen(src->DisableIntrinsicOption) + 1;
       
   378     char* s = NEW_C_HEAP_ARRAY(char, len, mtCompiler);
       
   379     strncpy(s, src->DisableIntrinsicOption, len);
       
   380     assert(s[len-1] == '\0', "");
       
   381     set->DisableIntrinsicOption = s;
       
   382   }
       
   383   return set;
       
   384 }
       
   385 
       
   386 // Create a new dirstack and push a default directive
       
   387 void DirectivesStack::init() {
       
   388   CompilerDirectives* _default_directives = new CompilerDirectives();
       
   389   char str[] = "*.*";
       
   390   const char* error_msg = NULL;
       
   391   _default_directives->add_match(str, error_msg);
       
   392 #ifdef COMPILER1
       
   393   _default_directives->_c1_store->EnableOption = true;
       
   394 #endif
       
   395 #ifdef COMPILER2
       
   396   _default_directives->_c2_store->EnableOption = true;
       
   397 #endif
       
   398   assert(error_msg == NULL, "Must succeed.");
       
   399   push(_default_directives);
       
   400 }
       
   401 
       
   402 DirectiveSet* DirectivesStack::getDefaultDirective(AbstractCompiler* comp) {
       
   403   MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag);
       
   404 
       
   405   assert(_bottom != NULL, "Must never be empty");
       
   406   return _bottom->get_for(comp);
       
   407 }
       
   408 
       
   409 void DirectivesStack::push(CompilerDirectives* directive) {
       
   410   MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag);
       
   411 
       
   412   directive->inc_refcount();
       
   413   if (_top == NULL) {
       
   414     assert(_bottom == NULL, "There can only be one default directive");
       
   415     _bottom = directive; // default directive, can never be removed.
       
   416   }
       
   417 
       
   418   directive->set_next(_top);
       
   419   _top = directive;
       
   420   _depth++;
       
   421 }
       
   422 
       
   423 void DirectivesStack::pop() {
       
   424   MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag);
       
   425   pop_inner();
       
   426 }
       
   427 
       
   428 void DirectivesStack::pop_inner() {
       
   429   assert(DirectivesStack_lock->owned_by_self(), "");
       
   430 
       
   431   if (_top->next() == NULL) {
       
   432     return; // Do nothing - don't allow an empty stack
       
   433   }
       
   434   CompilerDirectives* tmp = _top;
       
   435   _top = _top->next();
       
   436   _depth--;
       
   437 
       
   438   DirectivesStack::release(tmp);
       
   439 }
       
   440 
       
   441 void DirectivesStack::clear() {
       
   442   // holding the lock during the whole operation ensuring consistent result
       
   443   MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag);
       
   444   while (_top->next() != NULL) {
       
   445     pop_inner();
       
   446   }
       
   447 }
       
   448 
       
   449 void DirectivesStack::print(outputStream* st) {
       
   450   MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag);
       
   451   CompilerDirectives* tmp = _top;
       
   452   while (tmp != NULL) {
       
   453     tmp->print(st);
       
   454     tmp = tmp->next();
       
   455     st->cr();
       
   456   }
       
   457 }
       
   458 
       
   459 void DirectivesStack::release(DirectiveSet* set) {
       
   460   MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag);
       
   461   if (set->is_exclusive_copy()) {
       
   462     // Old CompilecCmmands forced us to create an exclusive copy
       
   463     delete set;
       
   464   } else {
       
   465     assert(set->directive() != NULL, "");
       
   466     release(set->directive());
       
   467   }
       
   468 }
       
   469 
       
   470 
       
   471 void DirectivesStack::release(CompilerDirectives* dir) {
       
   472   assert(DirectivesStack_lock->owned_by_self(), "");
       
   473   dir->dec_refcount();
       
   474   if (dir->refcount() == 0) {
       
   475     delete dir;
       
   476   }
       
   477 }
       
   478 
       
   479 DirectiveSet* DirectivesStack::getMatchingDirective(methodHandle method, AbstractCompiler *comp) {
       
   480   assert(_depth > 0, "Must never be empty");
       
   481   CompilerDirectives* dir = _top;
       
   482   assert(dir != NULL, "Must be initialized");
       
   483 
       
   484   DirectiveSet* match = NULL;
       
   485   {
       
   486     MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag);
       
   487     while (dir != NULL) {
       
   488       if (dir->is_default_directive() || dir->match(method)) {
       
   489         match = dir->get_for(comp);
       
   490         if (match->EnableOption) {
       
   491           // The directiveSet for this compile is also enabled -> success
       
   492           break;
       
   493         }
       
   494       }
       
   495       dir = dir->next();
       
   496     }
       
   497   }
       
   498 
       
   499   guarantee(match != NULL, "There should always be a default directive that matches");
       
   500   // Check for legacy compile commands update, without DirectivesStack_lock
       
   501   return match->compilecommand_compatibility_init(method);
       
   502 }