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/compilerDirectives.hpp"
  29 #include "compiler/compilerOracle.hpp"
  30 
  31 CompilerDirectives::CompilerDirectives() :_match(NULL), _next(NULL), _ref_count(0) {
  32   _c1_store = new DirectiveSet(this);
  33   _c2_store = new DirectiveSet(this);
  34 };
  35 
  36 CompilerDirectives::~CompilerDirectives() {
  37   if (_c1_store != NULL) {
  38     delete _c1_store;
  39   }
  40   if (_c2_store != NULL) {
  41     delete _c2_store;
  42   }
  43 
  44   // remove all linked method matchers
  45   BasicMatcher* tmp = _match;
  46   while (tmp != NULL) {
  47     BasicMatcher* next = tmp->next();
  48     delete tmp;
  49     tmp = next;
  50   }
  51 }
  52 
  53 void CompilerDirectives::print(outputStream* st) {
  54   st->cr();
  55   if (_match != NULL) {
  56     st->print_cr("Directive:");
  57     st->print(" matching: ");
  58     _match->print(st);
  59     BasicMatcher* tmp = _match->next();
  60     while (tmp != NULL) {
  61       st->print(", ");
  62       tmp->print(st);
  63       tmp = tmp->next();
  64     }
  65     st->cr();
  66   } else {
  67     assert(0, "There should always be a match");
  68   }
  69 
  70   if (_c1_store != NULL) {
  71     st->print_cr(" c1 directives:");
  72     _c1_store->print(st);
  73   }
  74   if (_c2_store != NULL) {
  75     st->print_cr(" c2 directives:");
  76     _c2_store->print(st);
  77   }
  78   //---
  79 }
  80 
  81 CompilerDirectives* CompilerDirectives::next() {
  82   return _next;
  83 }
  84 
  85 bool CompilerDirectives::match(methodHandle method, int comp_level) {
  86   if (method == NULL) {
  87     return false;
  88   }
  89   if (_match->match(method)) {
  90     return true;
  91   }
  92   return false;
  93 }
  94 
  95 bool CompilerDirectives::add_match(char* str, const char*& error_msg) {
  96   int bytes_read;
  97 
  98   BasicMatcher* bm = BasicMatcher::parse_method_pattern(str, error_msg);
  99   if (bm == NULL) {
 100     assert(error_msg != NULL, "Must have error message");
 101     return false;
 102   } else {
 103     bm->set_next(_match);
 104     _match = bm;
 105     return true;
 106   }
 107 }
 108 
 109 void CompilerDirectives::inc_refcount() {
 110   assert(DirectivesStack_lock->owned_by_self(), "");
 111   _ref_count++;
 112 }
 113 
 114 void CompilerDirectives::dec_refcount() {
 115   assert(DirectivesStack_lock->owned_by_self(), "");
 116   _ref_count--;
 117   if (_ref_count == 0) {
 118     delete this;
 119   }
 120 }
 121 
 122 DirectiveSet* CompilerDirectives::get_for(int comp_level) {
 123    assert(DirectivesStack_lock->owned_by_self(), "");
 124    inc_refcount(); // The compiling thread is responsible to decrement this when finished.
 125    assert((comp_level >= CompLevel_simple) && (comp_level <= CompLevel_full_optimization), "Outside bounds");
 126    if (comp_level == CompLevel_full_optimization) {
 127      return _c2_store;
 128    } else {
 129      return _c1_store;
 130    }
 131 }
 132 
 133 DirectiveSet::DirectiveSet(CompilerDirectives* d) :_inlinematchers(NULL), _directive(d) {
 134 #define init_defaults_definition(name, type, dvalue, compiler) this->name##Option = dvalue;
 135   compilerdirectives_common_flags(init_defaults_definition)
 136   compilerdirectives_c2_flags(init_defaults_definition)
 137   compilerdirectives_c1_flags(init_defaults_definition)
 138   memset(_modified, 0, sizeof _modified);
 139 }
 140 
 141 void DirectiveSet::release() {
 142   MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag);
 143   directive()->dec_refcount();
 144 }
 145 
 146 DirectiveSet::~DirectiveSet() {
 147   // remove all linked methodmatchers
 148   InlineMatcher* tmp = _inlinematchers;
 149   while (tmp != NULL) {
 150     InlineMatcher* next = tmp->next();
 151     delete tmp;
 152     tmp = next;
 153   }
 154 
 155 #ifdef COMPILER2
 156   // Free if modified, otherwise it just points to the global vm flag value
 157   if (_modified[DisableIntrinsicsIndex]) {
 158     FREE_C_HEAP_ARRAY(char, (void *)this->DisableIntrinsicsOption);
 159   }
 160 #endif
 161 }
 162 
 163 // Backward compatibility for CompileCommands
 164 // Breaks the abstraction and causes lots of extra complexity
 165 // - if some option is changed we need to copy dirset since it no longer can be shared
 166 // - Need to free copy after use
 167 // - Requires a modified bit so we don't overwrite options that is set by directives
 168 
 169 DirectiveSet* DirectiveSet::late_cc_init(methodHandle method) {
 170   // Early bail out - checking all options is expensive - we rely on them not being used
 171   // Only set a flag if it has not been modified and value changes.
 172   // Only copy set if a flag needs to be set
 173   if (CompileCommandCompatibilityOption && CompilerOracle::has_any_option()) {
 174     DirectiveSet* set = clone();
 175 
 176     bool changed = false; // Track if we actually change anything
 177 
 178     // All CompileCommands are not equal so this gets a bit verbose
 179     // When CompileCommands have been refactored less clutter will remain.
 180     if (CompilerOracle::should_break_at(method)) {
 181       if (!_modified[BreakAtCompileIndex] && !set->BreakAtCompileOption) {
 182         set->BreakAtCompileOption = true;
 183         changed = true;
 184       }
 185       if (!_modified[BreakAtExecuteIndex] && !set->BreakAtExecuteOption) {
 186         set->BreakAtExecuteOption = true;
 187         changed = true;
 188       }
 189     }
 190     if (CompilerOracle::should_log(method)) {
 191       if (!_modified[LogIndex] && !set->LogOption) {
 192         set->LogOption = true;
 193         changed = true;
 194       }
 195     }
 196     if (CompilerOracle::should_print(method)) {
 197       if (!_modified[PrintAssemblyIndex] && !set->PrintAssemblyOption) {
 198         set->PrintAssemblyOption = true;
 199         changed = true;
 200       }
 201     }
 202     // Exclude as in should not compile == Enabled
 203     if (CompilerOracle::should_exclude(method)) {
 204       if (!_modified[EnabledIndex] && !set->EnabledOption) {
 205         set->EnabledOption = true;
 206         changed = true;
 207       }
 208     }
 209 
 210     // inline and dontinline (including exclude) are implemented in the directiveset accessors
 211 #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) { this->name##Option = v; changed = true;} }
 212     compilerdirectives_common_flags(init_default_cc)
 213     compilerdirectives_c2_flags(init_default_cc)
 214     compilerdirectives_c1_flags(init_default_cc)
 215 
 216     if (!changed) {
 217       // We didn't actually update anything, discard.
 218       delete set;
 219     } else {
 220       // We are returning a (parentless) copy. The originals parent don't need to account for this.
 221       this->release();
 222       return set;
 223     }
 224   }
 225   // Nothing changed
 226   return this;
 227 }
 228 
 229 CompilerDirectives* DirectiveSet::directive() {
 230   assert(_directive != NULL, "Must have been initialized");
 231   return _directive;
 232 }
 233 
 234 bool DirectiveSet::matches_inline(methodHandle method, int inline_action) {
 235   if (_inlinematchers != NULL) {
 236     if (_inlinematchers->match(method, InlineMatcher::force_inline)) {
 237       return true;
 238     }
 239   }
 240   return false;
 241 }
 242 
 243 bool DirectiveSet::inline_commanded(ciMethod* inlinee) {
 244   inlinee->check_is_loaded();
 245   VM_ENTRY_MARK;
 246   methodHandle mh(THREAD, inlinee->get_Method());
 247 
 248   if (matches_inline(mh, InlineMatcher::force_inline)) {
 249     return true;
 250   }
 251   if (CompileCommandCompatibilityOption && CompilerOracle::should_inline(mh)) {
 252     return true;
 253   }
 254   return false;
 255 }
 256 
 257 bool DirectiveSet::dont_inline_commanded(ciMethod* inlinee) {
 258   inlinee->check_is_loaded();
 259   VM_ENTRY_MARK;
 260   methodHandle mh(THREAD, inlinee->get_Method());
 261 
 262   if (matches_inline(mh, InlineMatcher::dont_inline)) {
 263     return true;
 264   }
 265   if (CompileCommandCompatibilityOption && CompilerOracle::should_not_inline(mh)) {
 266     return true;
 267   }
 268   return false;
 269 }
 270 
 271 bool DirectiveSet::parse_and_add_inline(char* str, const char*& error_msg) {
 272   InlineMatcher* m = InlineMatcher::parse_inline_pattern(str, error_msg);
 273   if (m != NULL) {
 274     // add matcher last in chain - the order is significant
 275     append_inline(m);
 276     return true;
 277   } else {
 278     assert(error_msg != NULL, "Error message must be set");
 279     return false;
 280   }
 281 }
 282 
 283 void DirectiveSet::append_inline(InlineMatcher* m) {
 284   if (_inlinematchers == NULL) {
 285     _inlinematchers = m;
 286     return;
 287   }
 288   InlineMatcher* tmp = _inlinematchers;
 289   while (tmp->next() != NULL) {
 290     tmp = tmp->next();
 291   }
 292   tmp->set_next(m);
 293 }
 294 
 295 void DirectiveSet::print_inline(outputStream* st) {
 296   if (_inlinematchers == NULL) {
 297     st->print_cr("  inline: -");
 298   } else {
 299     st->print("  inline: ");
 300     _inlinematchers->print(st);
 301     InlineMatcher* tmp = _inlinematchers->next();
 302     while (tmp != NULL) {
 303       st->print(", ");
 304       tmp->print(st);
 305       tmp = tmp->next();
 306     }
 307     st->cr();
 308   }
 309 }
 310 
 311 bool DirectiveSet::is_intrinsic_disabled(methodHandle method) {
 312   vmIntrinsics::ID id = method->intrinsic_id();
 313   assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
 314 
 315   ccstr disable_intr =  DisableIntrinsicsOption;
 316   return ((disable_intr != '\0') && strstr(disable_intr, vmIntrinsics::name_at(id)) != NULL);
 317 }
 318 
 319 DirectiveSet* DirectiveSet::clone() {
 320   DirectiveSet* set = clone();
 321   memcpy(set->_modified, _modified, sizeof(_modified));
 322 
 323   InlineMatcher* tmp = _inlinematchers;
 324   while (tmp != NULL) {
 325     set->append_inline(tmp->clone());
 326     tmp = tmp->next();
 327   }
 328 
 329   #define copy_members_definition(name, type, dvalue, cc_flag) set->name##Option = name##Option;
 330     compilerdirectives_common_flags(copy_members_definition)
 331     compilerdirectives_c2_flags(copy_members_definition)
 332     compilerdirectives_c1_flags(copy_members_definition)
 333 
 334     // Must duplicate str option
 335     set->DisableIntrinsicsOption = os::strdup(DisableIntrinsicsOption, mtCompiler);
 336 
 337     return set;
 338 }