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 }