src/share/vm/compiler/compilerDirectives.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/compiler

src/share/vm/compiler/compilerDirectives.cpp

Print this page
rev 9918 : 8145331: SEGV in DirectivesStack::release(DirectiveSet*)
Summary: getDefaultDirective was not updated in 8144873
Reviewed-by:


 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++;


 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();


 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 }


 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   if (comp == NULL) { // Xint
 168     return _c1_store;
 169   } else  if (comp->is_c2()) {
 170     return _c2_store;
 171   } else {
 172     // use c1_store as default
 173     assert(comp->is_c1() || comp->is_jvmci() || comp->is_shark(), "");
 174     return _c1_store;




 175   }


 176 }
 177 
 178 // In the list of disabled intrinsics, the ID of the disabled intrinsics can separated:
 179 // - by ',' (if -XX:DisableIntrinsic is used once when invoking the VM) or
 180 // - by '\n' (if -XX:DisableIntrinsic is used multiple times when invoking the VM) or
 181 // - by ' ' (if DisableIntrinsic is used on a per-method level, e.g., with CompileCommand).
 182 //
 183 // To simplify the processing of the list, the canonicalize_disableintrinsic() method
 184 // returns a new copy of the list in which '\n' and ' ' is replaced with ','.
 185 ccstrlist DirectiveSet::canonicalize_disableintrinsic(ccstrlist option_value) {
 186   char* canonicalized_list = NEW_C_HEAP_ARRAY(char, strlen(option_value) + 1, mtCompiler);
 187   int i = 0;
 188   char current;
 189   while ((current = option_value[i]) != '\0') {
 190     if (current == '\n' || current == ' ') {
 191       canonicalized_list[i] = ',';
 192     } else {
 193       canonicalized_list[i] = current;
 194     }
 195     i++;


 437 // Create a new dirstack and push a default directive
 438 void DirectivesStack::init() {
 439   CompilerDirectives* _default_directives = new CompilerDirectives();
 440   char str[] = "*.*";
 441   const char* error_msg = NULL;
 442   _default_directives->add_match(str, error_msg);
 443 #ifdef COMPILER1
 444   _default_directives->_c1_store->EnableOption = true;
 445 #endif
 446 #ifdef COMPILER2
 447   _default_directives->_c2_store->EnableOption = true;
 448 #endif
 449   assert(error_msg == NULL, "Must succeed.");
 450   push(_default_directives);
 451 }
 452 
 453 DirectiveSet* DirectivesStack::getDefaultDirective(AbstractCompiler* comp) {
 454   MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag);
 455 
 456   assert(_bottom != NULL, "Must never be empty");
 457   _bottom->inc_refcount();
 458   return _bottom->get_for(comp);
 459 }
 460 
 461 void DirectivesStack::push(CompilerDirectives* directive) {
 462   MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag);
 463 
 464   directive->inc_refcount();
 465   if (_top == NULL) {
 466     assert(_bottom == NULL, "There can only be one default directive");
 467     _bottom = directive; // default directive, can never be removed.
 468   }
 469 
 470   directive->set_next(_top);
 471   _top = directive;
 472   _depth++;
 473 }
 474 
 475 void DirectivesStack::pop() {
 476   MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag);
 477   pop_inner();


 500 
 501 void DirectivesStack::clear() {
 502   // holding the lock during the whole operation ensuring consistent result
 503   MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag);
 504   while (_top->next() != NULL) {
 505     pop_inner();
 506   }
 507 }
 508 
 509 void DirectivesStack::print(outputStream* st) {
 510   MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag);
 511   CompilerDirectives* tmp = _top;
 512   while (tmp != NULL) {
 513     tmp->print(st);
 514     tmp = tmp->next();
 515     st->cr();
 516   }
 517 }
 518 
 519 void DirectivesStack::release(DirectiveSet* set) {
 520   assert(set != NULL, "Never NULL");
 521   MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag);
 522   if (set->is_exclusive_copy()) {
 523     // Old CompilecCmmands forced us to create an exclusive copy
 524     delete set;
 525   } else {
 526     assert(set->directive() != NULL, "Never NULL");
 527     release(set->directive());
 528   }
 529 }
 530 
 531 
 532 void DirectivesStack::release(CompilerDirectives* dir) {
 533   assert(DirectivesStack_lock->owned_by_self(), "");
 534   dir->dec_refcount();
 535   if (dir->refcount() == 0) {
 536     delete dir;
 537   }
 538 }
 539 
 540 DirectiveSet* DirectivesStack::getMatchingDirective(methodHandle method, AbstractCompiler *comp) {
 541   assert(_depth > 0, "Must never be empty");
 542 
 543   DirectiveSet* match = NULL;
 544   {
 545     MutexLockerEx locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag);
 546 
 547     CompilerDirectives* dir = _top;
 548     assert(dir != NULL, "Must be initialized");
 549 
 550     while (dir != NULL) {
 551       if (dir->is_default_directive() || dir->match(method)) {
 552         match = dir->get_for(comp);
 553         assert(match != NULL, "Consistency");








 554         if (match->EnableOption) {
 555           // The directiveSet for this compile is also enabled -> success
 556           dir->inc_refcount();
 557           break;
 558         }
 559       }

 560       dir = dir->next();
 561     }
 562   }

 563   guarantee(match != NULL, "There should always be a default directive that matches");
 564 
 565   // Check for legacy compile commands update, without DirectivesStack_lock
 566   return match->compilecommand_compatibility_init(method);
 567 }
src/share/vm/compiler/compilerDirectives.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File