33
33
34
34
CompilerDirectives::CompilerDirectives () : _next(NULL ), _match(NULL ), _ref_count(0 ) {
35
35
_c1_store = new DirectiveSet (this );
36
- _c1_store->init_disableintrinsic ();
36
+ _c1_store->init_control_intrinsic ();
37
37
_c2_store = new DirectiveSet (this );
38
- _c2_store->init_disableintrinsic ();
38
+ _c2_store->init_control_intrinsic ();
39
39
};
40
40
41
41
CompilerDirectives::~CompilerDirectives () {
@@ -179,14 +179,14 @@ DirectiveSet* CompilerDirectives::get_for(AbstractCompiler *comp) {
179
179
}
180
180
}
181
181
182
- // In the list of disabled intrinsics, the ID of the disabled intrinsics can separated:
183
- // - by ',' (if -XX:DisableIntrinsic is used once when invoking the VM) or
184
- // - by '\n' (if -XX:DisableIntrinsic is used multiple times when invoking the VM) or
185
- // - by ' ' (if DisableIntrinsic is used on a per-method level, e.g., with CompileCommand).
182
+ // In the list of Control/ disabled intrinsics, the ID of the control intrinsics can separated:
183
+ // - by ',' (if -XX:Control/ DisableIntrinsic is used once when invoking the VM) or
184
+ // - by '\n' (if -XX:Control/ DisableIntrinsic is used multiple times when invoking the VM) or
185
+ // - by ' ' (if Control/ DisableIntrinsic is used on a per-method level, e.g., with CompileCommand).
186
186
//
187
- // To simplify the processing of the list, the canonicalize_disableintrinsic () method
187
+ // To simplify the processing of the list, the canonicalize_control_intrinsic () method
188
188
// returns a new copy of the list in which '\n' and ' ' is replaced with ','.
189
- ccstrlist DirectiveSet::canonicalize_disableintrinsic (ccstrlist option_value) {
189
+ ccstrlist DirectiveSet::canonicalize_control_intrinsic (ccstrlist option_value) {
190
190
char * canonicalized_list = NEW_C_HEAP_ARRAY (char , strlen (option_value) + 1 , mtCompiler);
191
191
int i = 0 ;
192
192
char current;
@@ -202,9 +202,57 @@ ccstrlist DirectiveSet::canonicalize_disableintrinsic(ccstrlist option_value) {
202
202
return canonicalized_list;
203
203
}
204
204
205
- void DirectiveSet::init_disableintrinsic () {
206
- // Canonicalize DisableIntrinsic to contain only ',' as a separator.
207
- this ->DisableIntrinsicOption = canonicalize_disableintrinsic (DisableIntrinsic);
205
+ ControlIntrinsicIter::ControlIntrinsicIter (ccstrlist option_value, bool disable_all)
206
+ : _disableIntrinsic(disable_all) {
207
+ _list = (char *)DirectiveSet::canonicalize_control_intrinsic (option_value);
208
+ _saved_ptr = _list;
209
+ _enabled = false ;
210
+
211
+ _token = strtok_r (_saved_ptr, " ," , &_saved_ptr);
212
+ next_token ();
213
+ }
214
+
215
+ ControlIntrinsicIter::~ControlIntrinsicIter () {
216
+ FREE_C_HEAP_ARRAY (char , _list);
217
+ }
218
+
219
+ // pre-increment
220
+ ControlIntrinsicIter& ControlIntrinsicIter::operator ++() {
221
+ _token = strtok_r (NULL , " ," , &_saved_ptr);
222
+ next_token ();
223
+ return *this ;
224
+ }
225
+
226
+ void ControlIntrinsicIter::next_token () {
227
+ if (_token && !_disableIntrinsic) {
228
+ char ch = _token[0 ];
229
+
230
+ if (ch != ' +' && ch != ' -' ) {
231
+ warning (" failed to parse %s. must start with +/-!" , _token);
232
+ } else {
233
+ _enabled = ch == ' +' ;
234
+ _token++;
235
+ }
236
+ }
237
+ }
238
+
239
+ void DirectiveSet::init_control_intrinsic () {
240
+ for (ControlIntrinsicIter iter (ControlIntrinsic); *iter != NULL ; ++iter) {
241
+ vmIntrinsics::ID id = vmIntrinsics::find_id (*iter);
242
+
243
+ if (id != vmIntrinsics::_none) {
244
+ _intrinsic_control_words[id] = iter.is_enabled ();
245
+ }
246
+ }
247
+
248
+ // Order matters, DisableIntrinsic can overwrite ControlIntrinsic
249
+ for (ControlIntrinsicIter iter (DisableIntrinsic, true /* disable_all*/ ); *iter != NULL ; ++iter) {
250
+ vmIntrinsics::ID id = vmIntrinsics::find_id (*iter);
251
+
252
+ if (id != vmIntrinsics::_none) {
253
+ _intrinsic_control_words[id] = false ;
254
+ }
255
+ }
208
256
}
209
257
210
258
DirectiveSet::DirectiveSet (CompilerDirectives* d) :_inlinematchers(NULL ), _directive(d) {
@@ -213,6 +261,7 @@ DirectiveSet::DirectiveSet(CompilerDirectives* d) :_inlinematchers(NULL), _direc
213
261
compilerdirectives_c2_flags (init_defaults_definition)
214
262
compilerdirectives_c1_flags (init_defaults_definition)
215
263
memset (_modified, 0 , sizeof (_modified));
264
+ _intrinsic_control_words.fill_in (/* default value*/ TriBool ());
216
265
}
217
266
218
267
DirectiveSet::~DirectiveSet () {
@@ -223,12 +272,6 @@ DirectiveSet::~DirectiveSet() {
223
272
delete tmp;
224
273
tmp = next;
225
274
}
226
-
227
- // When constructed, DirectiveSet canonicalizes the DisableIntrinsic flag
228
- // into a new string. Therefore, that string is deallocated when
229
- // the DirectiveSet is destroyed.
230
- assert (this ->DisableIntrinsicOption != NULL , " " );
231
- FREE_C_HEAP_ARRAY (char , (void *)this ->DisableIntrinsicOption );
232
275
}
233
276
234
277
// Backward compatibility for CompileCommands
@@ -280,10 +323,6 @@ DirectiveSet* DirectiveSet::compilecommand_compatibility_init(const methodHandle
280
323
}
281
324
}
282
325
283
- // Read old value of DisableIntrinsicOption, in case we need to free it
284
- // and overwrite it with a new value.
285
- ccstrlist old_disable_intrinsic_value = set->DisableIntrinsicOption ;
286
-
287
326
// inline and dontinline (including exclude) are implemented in the directiveset accessors
288
327
#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 ;} }
289
328
compilerdirectives_common_flags (init_default_cc)
@@ -292,11 +331,45 @@ DirectiveSet* DirectiveSet::compilecommand_compatibility_init(const methodHandle
292
331
293
332
// Canonicalize DisableIntrinsic to contain only ',' as a separator.
294
333
ccstrlist option_value;
334
+ bool need_reset = true ; // if Control/DisableIntrinsic redefined, only need to reset control_words once
335
+
336
+ if (!_modified[ControlIntrinsicIndex] &&
337
+ CompilerOracle::has_option_value (method, " ControlIntrinsic" , option_value)) {
338
+ ControlIntrinsicIter iter (option_value);
339
+
340
+ if (need_reset) {
341
+ set->_intrinsic_control_words .fill_in (TriBool ());
342
+ need_reset = false ;
343
+ }
344
+
345
+ while (*iter != NULL ) {
346
+ vmIntrinsics::ID id = vmIntrinsics::find_id (*iter);
347
+ if (id != vmIntrinsics::_none) {
348
+ set->_intrinsic_control_words [id] = iter.is_enabled ();
349
+ }
350
+
351
+ ++iter;
352
+ }
353
+ }
354
+
355
+
295
356
if (!_modified[DisableIntrinsicIndex] &&
296
357
CompilerOracle::has_option_value (method, " DisableIntrinsic" , option_value)) {
297
- set->DisableIntrinsicOption = canonicalize_disableintrinsic (option_value);
298
- assert (old_disable_intrinsic_value != NULL , " " );
299
- FREE_C_HEAP_ARRAY (char , (void *)old_disable_intrinsic_value);
358
+ ControlIntrinsicIter iter (option_value, true /* disable_all*/ );
359
+
360
+ if (need_reset) {
361
+ set->_intrinsic_control_words .fill_in (TriBool ());
362
+ need_reset = false ;
363
+ }
364
+
365
+ while (*iter != NULL ) {
366
+ vmIntrinsics::ID id = vmIntrinsics::find_id (*iter);
367
+ if (id != vmIntrinsics::_none) {
368
+ set->_intrinsic_control_words [id] = false ;
369
+ }
370
+
371
+ ++iter;
372
+ }
300
373
}
301
374
302
375
@@ -397,38 +470,23 @@ void DirectiveSet::print_inline(outputStream* st) {
397
470
398
471
bool DirectiveSet::is_intrinsic_disabled (const methodHandle& method) {
399
472
vmIntrinsics::ID id = method->intrinsic_id ();
400
- assert (id != vmIntrinsics::_none, " must be a VM intrinsic" );
401
-
402
- ResourceMark rm;
403
-
404
- // Create a copy of the string that contains the list of disabled
405
- // intrinsics. The copy is created because the string
406
- // will be modified by strtok(). Then, the list is tokenized with
407
- // ',' as a separator.
408
- size_t length = strlen (DisableIntrinsicOption);
409
- char * local_list = NEW_RESOURCE_ARRAY (char , length + 1 );
410
- strncpy (local_list, DisableIntrinsicOption, length + 1 );
411
- char * save_ptr;
412
-
413
- char * token = strtok_r (local_list, " ," , &save_ptr);
414
- while (token != NULL ) {
415
- if (strcmp (token, vmIntrinsics::name_at (id)) == 0 ) {
416
- return true ;
417
- } else {
418
- token = strtok_r (NULL , " ," , &save_ptr);
419
- }
420
- }
473
+ assert (id > vmIntrinsics::_none && id < vmIntrinsics::ID_LIMIT, " invalid intrinsic_id!" );
421
474
422
- return false ;
475
+ TriBool b = _intrinsic_control_words[id];
476
+ if (b.is_default ()) {
477
+ return false ; // if unset, every intrinsic is enabled.
478
+ } else {
479
+ return !b;
480
+ }
423
481
}
424
482
425
483
DirectiveSet* DirectiveSet::clone (DirectiveSet const * src) {
426
484
DirectiveSet* set = new DirectiveSet (NULL );
427
- // Ordinary allocations of DirectiveSet would call init_disableintrinsic ()
428
- // immediately to create a new copy for set->DisableIntrinsicOption.
485
+ // Ordinary allocations of DirectiveSet would call init_control_intrinsic ()
486
+ // immediately to create a new copy for set->Control/ DisableIntrinsicOption.
429
487
// However, here it does not need to because the code below creates
430
- // a copy of src->DisableIntrinsicOption that initializes
431
- // set->DisableIntrinsicOption.
488
+ // a copy of src->Control/ DisableIntrinsicOption that initializes
489
+ // set->Control/ DisableIntrinsicOption.
432
490
433
491
memcpy (set->_modified , src->_modified , sizeof (src->_modified ));
434
492
@@ -443,13 +501,7 @@ DirectiveSet* DirectiveSet::clone(DirectiveSet const* src) {
443
501
compilerdirectives_c2_flags (copy_members_definition)
444
502
compilerdirectives_c1_flags (copy_members_definition)
445
503
446
- // Create a local copy of the DisableIntrinsicOption.
447
- assert (src->DisableIntrinsicOption != NULL , " " );
448
- size_t len = strlen (src->DisableIntrinsicOption ) + 1 ;
449
- char * s = NEW_C_HEAP_ARRAY (char , len, mtCompiler);
450
- strncpy (s, src->DisableIntrinsicOption , len);
451
- assert (s[len-1 ] == ' \0 ' , " " );
452
- set->DisableIntrinsicOption = s;
504
+ set->_intrinsic_control_words = src->_intrinsic_control_words ;
453
505
return set;
454
506
}
455
507
0 commit comments