@@ -49,6 +49,8 @@ bool CDSConfig::_is_using_optimized_module_handling = true;
49
49
bool CDSConfig::_is_dumping_full_module_graph = true ;
50
50
bool CDSConfig::_is_using_full_module_graph = true ;
51
51
bool CDSConfig::_has_aot_linked_classes = false ;
52
+ bool CDSConfig::_is_single_command_training = false ;
53
+ bool CDSConfig::_has_temp_aot_config_file = false ;
52
54
bool CDSConfig::_old_cds_flags_used = false ;
53
55
bool CDSConfig::_new_aot_flags_used = false ;
54
56
bool CDSConfig::_disable_heap_dumping = false ;
@@ -398,12 +400,14 @@ void CDSConfig::check_aot_flags() {
398
400
_old_cds_flags_used = true ;
399
401
}
400
402
401
- // "New" AOT flags must not be mixed with "classic" flags such as -Xshare:dump
403
+ // "New" AOT flags must not be mixed with "classic" CDS flags such as -Xshare:dump
402
404
CHECK_NEW_FLAG (AOTCache);
405
+ CHECK_NEW_FLAG (AOTCacheOutput);
403
406
CHECK_NEW_FLAG (AOTConfiguration);
404
407
CHECK_NEW_FLAG (AOTMode);
405
408
406
409
CHECK_SINGLE_PATH (AOTCache);
410
+ CHECK_SINGLE_PATH (AOTCacheOutput);
407
411
CHECK_SINGLE_PATH (AOTConfiguration);
408
412
409
413
if (FLAG_IS_DEFAULT (AOTCache) && AOTAdapterCaching) {
@@ -413,29 +417,41 @@ void CDSConfig::check_aot_flags() {
413
417
log_debug (aot,codecache,init)(" AOTCache is not specified - AOTStubCaching is ignored" );
414
418
}
415
419
416
- if (FLAG_IS_DEFAULT (AOTCache) && FLAG_IS_DEFAULT (AOTConfiguration) && FLAG_IS_DEFAULT (AOTMode)) {
417
- // AOTCache/AOTConfiguration/AOTMode not used -> using the "classic CDS" workflow.
420
+ bool has_cache = !FLAG_IS_DEFAULT (AOTCache);
421
+ bool has_cache_output = !FLAG_IS_DEFAULT (AOTCacheOutput);
422
+ bool has_config = !FLAG_IS_DEFAULT (AOTConfiguration);
423
+ bool has_mode = !FLAG_IS_DEFAULT (AOTMode);
424
+
425
+ if (!has_cache && !has_cache_output && !has_config && !has_mode) {
426
+ // AOT flags are not used. Use classic CDS workflow
418
427
return ;
419
- } else {
420
- _new_aot_flags_used = true ;
421
428
}
422
429
430
+ if (has_cache && has_cache_output) {
431
+ vm_exit_during_initialization (" Only one of AOTCache or AOTCacheOutput can be specified" );
432
+ }
433
+
434
+ if (!has_cache && (!has_mode || strcmp (AOTMode, " auto" ) == 0 )) {
435
+ if (has_cache_output) {
436
+ // If AOTCacheOutput has been set, effective mode is "record".
437
+ // Default value for AOTConfiguration, if necessary, will be assigned in check_aotmode_record().
438
+ log_info (aot)(" Selected AOTMode=record because AOTCacheOutput is specified" );
439
+ FLAG_SET_ERGO (AOTMode, " record" );
440
+ }
441
+ }
442
+
443
+ // At least one AOT flag has been used
444
+ _new_aot_flags_used = true ;
445
+
423
446
if (FLAG_IS_DEFAULT (AOTMode) || strcmp (AOTMode, " auto" ) == 0 || strcmp (AOTMode, " on" ) == 0 ) {
424
447
check_aotmode_auto_or_on ();
425
448
} else if (strcmp (AOTMode, " off" ) == 0 ) {
426
449
check_aotmode_off ();
450
+ } else if (strcmp (AOTMode, " record" ) == 0 ) {
451
+ check_aotmode_record ();
427
452
} else {
428
- // AOTMode is record or create
429
- if (FLAG_IS_DEFAULT (AOTConfiguration)) {
430
- vm_exit_during_initialization (err_msg (" -XX:AOTMode=%s cannot be used without setting AOTConfiguration" , AOTMode));
431
- }
432
-
433
- if (strcmp (AOTMode, " record" ) == 0 ) {
434
- check_aotmode_record ();
435
- } else {
436
- assert (strcmp (AOTMode, " create" ) == 0 , " checked by AOTModeConstraintFunc" );
437
- check_aotmode_create ();
438
- }
453
+ assert (strcmp (AOTMode, " create" ) == 0 , " checked by AOTModeConstraintFunc" );
454
+ check_aotmode_create ();
439
455
}
440
456
441
457
// This is an old flag used by CDS regression testing only. It doesn't apply
@@ -450,7 +466,8 @@ void CDSConfig::check_aotmode_off() {
450
466
451
467
void CDSConfig::check_aotmode_auto_or_on () {
452
468
if (!FLAG_IS_DEFAULT (AOTConfiguration)) {
453
- vm_exit_during_initialization (" AOTConfiguration can only be used with -XX:AOTMode=record or -XX:AOTMode=create" );
469
+ vm_exit_during_initialization (err_msg (" AOTConfiguration can only be used with when AOTMode is record or create (selected AOTMode = %s)" ,
470
+ FLAG_IS_DEFAULT (AOTMode) ? " auto" : AOTMode));
454
471
}
455
472
456
473
UseSharedSpaces = true ;
@@ -462,11 +479,63 @@ void CDSConfig::check_aotmode_auto_or_on() {
462
479
}
463
480
}
464
481
482
+ // %p substitution in AOTCache, AOTCacheOutput and AOTCacheConfiguration
483
+ static void substitute_aot_filename (JVMFlagsEnum flag_enum) {
484
+ JVMFlag* flag = JVMFlag::flag_from_enum (flag_enum);
485
+ const char * filename = flag->read <const char *>();
486
+ assert (filename != nullptr , " must not have default value" );
487
+
488
+ // For simplicity, we don't allow %p/%t to be specified twice, because make_log_name()
489
+ // substitutes only the first occurrence. Otherwise, if we run with
490
+ // java -XX:AOTCacheOutput=%p%p.aot
491
+ // it will end up with both the pid of the training process and the assembly process.
492
+ const char * first_p = strstr (filename, " %p" );
493
+ if (first_p != nullptr && strstr (first_p + 2 , " %p" ) != nullptr ) {
494
+ vm_exit_during_initialization (err_msg (" %s cannot contain more than one %%p" , flag->name ()));
495
+ }
496
+ const char * first_t = strstr (filename, " %t" );
497
+ if (first_t != nullptr && strstr (first_t + 2 , " %t" ) != nullptr ) {
498
+ vm_exit_during_initialization (err_msg (" %s cannot contain more than one %%t" , flag->name ()));
499
+ }
500
+
501
+ // Note: with single-command training, %p will be the pid of the training process, not the
502
+ // assembly process.
503
+ const char * new_filename = make_log_name (filename, nullptr );
504
+ if (strcmp (filename, new_filename) != 0 ) {
505
+ JVMFlag::Error err = JVMFlagAccess::set_ccstr (flag, &new_filename, JVMFlagOrigin::ERGONOMIC);
506
+ assert (err == JVMFlag::SUCCESS, " must never fail" );
507
+ }
508
+ FREE_C_HEAP_ARRAY (char , new_filename);
509
+ }
510
+
465
511
void CDSConfig::check_aotmode_record () {
512
+ bool has_config = !FLAG_IS_DEFAULT (AOTConfiguration);
513
+ bool has_output = !FLAG_IS_DEFAULT (AOTCacheOutput);
514
+
515
+ if (!has_output && !has_config) {
516
+ vm_exit_during_initialization (" At least one of AOTCacheOutput and AOTConfiguration must be specified when using -XX:AOTMode=record" );
517
+ }
518
+
519
+ if (has_output) {
520
+ _is_single_command_training = true ;
521
+ substitute_aot_filename (FLAG_MEMBER_ENUM (AOTCacheOutput));
522
+ if (!has_config) {
523
+ // Too early; can't use resource allocation yet.
524
+ size_t len = strlen (AOTCacheOutput) + 10 ;
525
+ char * temp = AllocateHeap (len, mtArguments);
526
+ jio_snprintf (temp, len, " %s.config" , AOTCacheOutput);
527
+ FLAG_SET_ERGO (AOTConfiguration, temp);
528
+ FreeHeap (temp);
529
+ _has_temp_aot_config_file = true ;
530
+ }
531
+ }
532
+
466
533
if (!FLAG_IS_DEFAULT (AOTCache)) {
467
534
vm_exit_during_initialization (" AOTCache must not be specified when using -XX:AOTMode=record" );
468
535
}
469
536
537
+ substitute_aot_filename (FLAG_MEMBER_ENUM (AOTConfiguration));
538
+
470
539
UseSharedSpaces = false ;
471
540
RequireSharedSpaces = false ;
472
541
_is_dumping_static_archive = true ;
@@ -478,10 +547,27 @@ void CDSConfig::check_aotmode_record() {
478
547
}
479
548
480
549
void CDSConfig::check_aotmode_create () {
481
- if (FLAG_IS_DEFAULT (AOTCache )) {
482
- vm_exit_during_initialization (" AOTCache must be specified when using -XX:AOTMode=create" );
550
+ if (FLAG_IS_DEFAULT (AOTConfiguration )) {
551
+ vm_exit_during_initialization (" AOTConfiguration must be specified when using -XX:AOTMode=create" );
483
552
}
484
553
554
+ bool has_cache = !FLAG_IS_DEFAULT (AOTCache);
555
+ bool has_cache_output = !FLAG_IS_DEFAULT (AOTCacheOutput);
556
+
557
+ assert (!(has_cache && has_cache_output), " already checked" );
558
+
559
+ if (!has_cache && !has_cache_output) {
560
+ vm_exit_during_initialization (" AOTCache or AOTCacheOutput must be specified when using -XX:AOTMode=create" );
561
+ }
562
+
563
+ if (!has_cache) {
564
+ precond (has_cache_output);
565
+ FLAG_SET_ERGO (AOTCache, AOTCacheOutput);
566
+ }
567
+ // No need to check for (!has_cache_output), as we don't look at AOTCacheOutput after here.
568
+
569
+ substitute_aot_filename (FLAG_MEMBER_ENUM (AOTCache));
570
+
485
571
_is_dumping_final_static_archive = true ;
486
572
UseSharedSpaces = true ;
487
573
RequireSharedSpaces = true ;
0 commit comments