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

src/share/vm/compiler/compilerDirectives.cpp

Print this page




 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)) {


 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) {


 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) {




 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 // 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++;
 196   }
 197   canonicalized_list[i] = '\0';
 198   return canonicalized_list;
 199 }
 200 
 201 DirectiveSet::DirectiveSet(CompilerDirectives* d) :_inlinematchers(NULL), _directive(d) {
 202 #define init_defaults_definition(name, type, dvalue, compiler) this->name##Option = dvalue;
 203   compilerdirectives_common_flags(init_defaults_definition)
 204   compilerdirectives_c2_flags(init_defaults_definition)
 205   compilerdirectives_c1_flags(init_defaults_definition)
 206   memset(_modified, 0, sizeof _modified);
 207 
 208   // Canonicalize DisableIntrinsic to contain only ',' as a separator.
 209   this->DisableIntrinsicOption = canonicalize_disableintrinsic(DisableIntrinsic);
 210 }
 211 
 212 DirectiveSet::~DirectiveSet() {
 213   // remove all linked methodmatchers
 214   InlineMatcher* tmp = _inlinematchers;
 215   while (tmp != NULL) {
 216     InlineMatcher* next = tmp->next();
 217     delete tmp;
 218     tmp = next;
 219   }
 220 
 221   // When constructed, DirectiveSet canonicalizes the DisableIntrinsic flag
 222   // into a new string. Therefore, that string is deallocated when
 223   // the DirectiveSet is destroyed.
 224   assert(this->DisableIntrinsicOption != NULL, "");
 225   FREE_C_HEAP_ARRAY(char, (void *)this->DisableIntrinsicOption);

 226 }
 227 
 228 // Backward compatibility for CompileCommands
 229 // Breaks the abstraction and causes lots of extra complexity
 230 // - if some option is changed we need to copy directiveset since it no longer can be shared
 231 // - Need to free copy after use
 232 // - Requires a modified bit so we don't overwrite options that is set by directives
 233 
 234 DirectiveSet* DirectiveSet::compilecommand_compatibility_init(methodHandle method) {
 235   // Early bail out - checking all options is expensive - we rely on them not being used
 236   // Only set a flag if it has not been modified and value changes.
 237   // Only copy set if a flag needs to be set
 238   if (!CompilerDirectivesIgnoreCompileCommandsOption && CompilerOracle::has_any_option()) {
 239     DirectiveSet* set = DirectiveSet::clone(this);
 240 
 241     bool changed = false; // Track if we actually change anything
 242 
 243     // All CompileCommands are not equal so this gets a bit verbose
 244     // When CompileCommands have been refactored less clutter will remain.
 245     if (CompilerOracle::should_break_at(method)) {


 261     if (CompilerOracle::should_print(method)) {
 262       if (!_modified[PrintAssemblyIndex]) {
 263         set->PrintAssemblyOption = true;
 264         changed = true;
 265       }
 266     }
 267     // Exclude as in should not compile == Enabled
 268     if (CompilerOracle::should_exclude(method)) {
 269       if (!_modified[ExcludeIndex]) {
 270         set->ExcludeOption = true;
 271         changed = true;
 272       }
 273     }
 274 
 275     // inline and dontinline (including exclude) are implemented in the directiveset accessors
 276 #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;} }
 277     compilerdirectives_common_flags(init_default_cc)
 278     compilerdirectives_c2_flags(init_default_cc)
 279     compilerdirectives_c1_flags(init_default_cc)
 280 
 281     // Canonicalize DisableIntrinsic to contain only ',' as a separator.
 282     ccstrlist option_value;
 283     if (!_modified[DisableIntrinsicIndex] &&
 284         CompilerOracle::has_option_value(method, "DisableIntrinsic", option_value)) {
 285       set->DisableIntrinsicOption = canonicalize_disableintrinsic(option_value);
 286     }
 287 
 288 
 289     if (!changed) {
 290       // We didn't actually update anything, discard.
 291       delete set;
 292     } else {
 293       // We are returning a (parentless) copy. The originals parent don't need to account for this.
 294       DirectivesStack::release(this);
 295       return set;
 296     }
 297   }
 298   // Nothing changed
 299   return this;
 300 }
 301 
 302 CompilerDirectives* DirectiveSet::directive() {
 303   assert(_directive != NULL, "Must have been initialized");
 304   return _directive;
 305 }
 306 
 307 bool DirectiveSet::matches_inline(methodHandle method, int inline_action) {
 308   if (_inlinematchers != NULL) {


 368 void DirectiveSet::print_inline(outputStream* st) {
 369   if (_inlinematchers == NULL) {
 370     st->print_cr("  inline: -");
 371   } else {
 372     st->print("  inline: ");
 373     _inlinematchers->print(st);
 374     InlineMatcher* tmp = _inlinematchers->next();
 375     while (tmp != NULL) {
 376       st->print(", ");
 377       tmp->print(st);
 378       tmp = tmp->next();
 379     }
 380     st->cr();
 381   }
 382 }
 383 
 384 bool DirectiveSet::is_intrinsic_disabled(methodHandle method) {
 385   vmIntrinsics::ID id = method->intrinsic_id();
 386   assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
 387 
 388   ResourceMark rm;
 389 
 390   // Create a copy of the string that contains the list of disabled
 391   // intrinsics. The copy is created because the string
 392   // will be modified by strtok(). Then, the list is tokenized with
 393   // ',' as a separator.
 394   size_t length = strlen(DisableIntrinsicOption);
 395   char* local_list = NEW_RESOURCE_ARRAY(char, length + 1);
 396   strncpy(local_list, DisableIntrinsicOption, length + 1);
 397 
 398   char* token = strtok(local_list, ",");
 399   while (token != NULL) {
 400     if (strcmp(token, vmIntrinsics::name_at(id)) == 0) {
 401       return true;
 402     } else {
 403       token = strtok(NULL, ",");
 404     }
 405   }
 406 
 407   return false;
 408 }
 409 
 410 DirectiveSet* DirectiveSet::clone(DirectiveSet const* src) {
 411   DirectiveSet* set = new DirectiveSet(NULL);
 412   memcpy(set->_modified, src->_modified, sizeof(src->_modified));
 413 
 414   InlineMatcher* tmp = src->_inlinematchers;
 415   while (tmp != NULL) {
 416     set->append_inline(tmp->clone());
 417     tmp = tmp->next();
 418   }
 419 
 420   #define copy_members_definition(name, type, dvalue, cc_flag) set->name##Option = src->name##Option;
 421     compilerdirectives_common_flags(copy_members_definition)
 422     compilerdirectives_c2_flags(copy_members_definition)
 423     compilerdirectives_c1_flags(copy_members_definition)
 424 
 425   // Create a local copy of the DisableIntrinsicOption.

 426   assert(src->DisableIntrinsicOption != NULL, "");
 427   size_t len = strlen(src->DisableIntrinsicOption) + 1;
 428   char* s = NEW_C_HEAP_ARRAY(char, len, mtCompiler);
 429   strncpy(s, src->DisableIntrinsicOption, len);
 430   assert(s[len-1] == '\0', "");
 431   set->DisableIntrinsicOption = s;

 432   return set;
 433 }
 434 
 435 // Create a new dirstack and push a default directive
 436 void DirectivesStack::init() {
 437   CompilerDirectives* _default_directives = new CompilerDirectives();
 438   char str[] = "*.*";
 439   const char* error_msg = NULL;
 440   _default_directives->add_match(str, error_msg);
 441 #ifdef COMPILER1
 442   _default_directives->_c1_store->EnableOption = true;
 443 #endif
 444 #ifdef COMPILER2
 445   _default_directives->_c2_store->EnableOption = true;
 446 #endif
 447   assert(error_msg == NULL, "Must succeed.");
 448   push(_default_directives);
 449 }
 450 
 451 DirectiveSet* DirectivesStack::getDefaultDirective(AbstractCompiler* comp) {


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