8353597: Refactor handling VM options for AOT cache input and output

Reviewed-by: kvn, asmehra
This commit is contained in:
Ioi Lam 2025-04-09 15:03:38 +00:00
parent 4dc9e58906
commit 567c6885a3
15 changed files with 254 additions and 148 deletions

View File

@ -51,9 +51,10 @@ bool CDSConfig::_old_cds_flags_used = false;
bool CDSConfig::_new_aot_flags_used = false; bool CDSConfig::_new_aot_flags_used = false;
bool CDSConfig::_disable_heap_dumping = false; bool CDSConfig::_disable_heap_dumping = false;
char* CDSConfig::_default_archive_path = nullptr; const char* CDSConfig::_default_archive_path = nullptr;
char* CDSConfig::_static_archive_path = nullptr; const char* CDSConfig::_input_static_archive_path = nullptr;
char* CDSConfig::_dynamic_archive_path = nullptr; const char* CDSConfig::_input_dynamic_archive_path = nullptr;
const char* CDSConfig::_output_archive_path = nullptr;
JavaThread* CDSConfig::_dumper_thread = nullptr; JavaThread* CDSConfig::_dumper_thread = nullptr;
@ -66,7 +67,11 @@ int CDSConfig::get_status() {
(is_using_archive() ? IS_USING_ARCHIVE : 0); (is_using_archive() ? IS_USING_ARCHIVE : 0);
} }
void CDSConfig::initialize() { DEBUG_ONLY(static bool _cds_ergo_initialize_started = false);
void CDSConfig::ergo_initialize() {
DEBUG_ONLY(_cds_ergo_initialize_started = true);
if (is_dumping_static_archive() && !is_dumping_final_static_archive()) { if (is_dumping_static_archive() && !is_dumping_final_static_archive()) {
// Note: -Xshare and -XX:AOTMode flags are mutually exclusive. // Note: -Xshare and -XX:AOTMode flags are mutually exclusive.
// - Classic workflow: -Xshare:on and -Xshare:dump cannot take effect at the same time. // - Classic workflow: -Xshare:on and -Xshare:dump cannot take effect at the same time.
@ -83,10 +88,12 @@ void CDSConfig::initialize() {
// Initialize shared archive paths which could include both base and dynamic archive paths // Initialize shared archive paths which could include both base and dynamic archive paths
// This must be after set_ergonomics_flags() called so flag UseCompressedOops is set properly. // This must be after set_ergonomics_flags() called so flag UseCompressedOops is set properly.
//
// UseSharedSpaces may be disabled if -XX:SharedArchiveFile is invalid.
if (is_dumping_static_archive() || is_using_archive()) { if (is_dumping_static_archive() || is_using_archive()) {
init_shared_archive_paths(); if (new_aot_flags_used()) {
ergo_init_aot_paths();
} else {
ergo_init_classic_archive_paths();
}
} }
if (!is_dumping_heap()) { if (!is_dumping_heap()) {
@ -94,7 +101,10 @@ void CDSConfig::initialize() {
} }
} }
char* CDSConfig::default_archive_path() { const char* CDSConfig::default_archive_path() {
// The path depends on UseCompressedOops, etc, which are set by GC ergonomics just
// before CDSConfig::ergo_initialize() is called.
assert(_cds_ergo_initialize_started, "sanity");
if (_default_archive_path == nullptr) { if (_default_archive_path == nullptr) {
stringStream tmp; stringStream tmp;
const char* subdir = WINDOWS_ONLY("bin") NOT_WINDOWS("lib"); const char* subdir = WINDOWS_ONLY("bin") NOT_WINDOWS("lib");
@ -116,12 +126,12 @@ char* CDSConfig::default_archive_path() {
return _default_archive_path; return _default_archive_path;
} }
int CDSConfig::num_archives(const char* archive_path) { int CDSConfig::num_archive_paths(const char* path_spec) {
if (archive_path == nullptr) { if (path_spec == nullptr) {
return 0; return 0;
} }
int npaths = 1; int npaths = 1;
char* p = (char*)archive_path; char* p = (char*)path_spec;
while (*p != '\0') { while (*p != '\0') {
if (*p == os::path_separator()[0]) { if (*p == os::path_separator()[0]) {
npaths++; npaths++;
@ -131,9 +141,9 @@ int CDSConfig::num_archives(const char* archive_path) {
return npaths; return npaths;
} }
void CDSConfig::extract_shared_archive_paths(const char* archive_path, void CDSConfig::extract_archive_paths(const char* archive_path,
char** base_archive_path, const char** base_archive_path,
char** top_archive_path) { const char** top_archive_path) {
char* begin_ptr = (char*)archive_path; char* begin_ptr = (char*)archive_path;
char* end_ptr = strchr((char*)archive_path, os::path_separator()[0]); char* end_ptr = strchr((char*)archive_path, os::path_separator()[0]);
if (end_ptr == nullptr || end_ptr == begin_ptr) { if (end_ptr == nullptr || end_ptr == begin_ptr) {
@ -157,7 +167,8 @@ void CDSConfig::extract_shared_archive_paths(const char* archive_path,
*top_archive_path = cur_path; *top_archive_path = cur_path;
} }
void CDSConfig::init_shared_archive_paths() { void CDSConfig::ergo_init_classic_archive_paths() {
assert(_cds_ergo_initialize_started, "sanity");
if (ArchiveClassesAtExit != nullptr) { if (ArchiveClassesAtExit != nullptr) {
assert(!RecordDynamicDumpInfo, "already checked"); assert(!RecordDynamicDumpInfo, "already checked");
if (is_dumping_static_archive()) { if (is_dumping_static_archive()) {
@ -172,21 +183,24 @@ void CDSConfig::init_shared_archive_paths() {
} }
if (SharedArchiveFile == nullptr) { if (SharedArchiveFile == nullptr) {
_static_archive_path = default_archive_path(); _input_static_archive_path = default_archive_path();
if (is_dumping_static_archive()) {
_output_archive_path = _input_static_archive_path;
}
} else { } else {
int archives = num_archives(SharedArchiveFile); int num_archives = num_archive_paths(SharedArchiveFile);
assert(archives > 0, "must be"); assert(num_archives > 0, "must be");
if (is_dumping_archive() && archives > 1) { if (is_dumping_archive() && num_archives > 1) {
vm_exit_during_initialization( vm_exit_during_initialization(
"Cannot have more than 1 archive file specified in -XX:SharedArchiveFile during CDS dumping"); "Cannot have more than 1 archive file specified in -XX:SharedArchiveFile during CDS dumping");
} }
if (is_dumping_static_archive()) { if (is_dumping_static_archive()) {
assert(archives == 1, "must be"); assert(num_archives == 1, "just checked above");
// Static dump is simple: only one archive is allowed in SharedArchiveFile. This file // Static dump is simple: only one archive is allowed in SharedArchiveFile. This file
// will be overwritten no matter regardless of its contents // will be overwritten regardless of its contents
_static_archive_path = os::strdup_check_oom(SharedArchiveFile, mtArguments); _output_archive_path = SharedArchiveFile;
} else { } else {
// SharedArchiveFile may specify one or two files. In case (c), the path for base.jsa // SharedArchiveFile may specify one or two files. In case (c), the path for base.jsa
// is read from top.jsa // is read from top.jsa
@ -197,48 +211,49 @@ void CDSConfig::init_shared_archive_paths() {
// However, if either RecordDynamicDumpInfo or ArchiveClassesAtExit is used, we do not // However, if either RecordDynamicDumpInfo or ArchiveClassesAtExit is used, we do not
// allow cases (b) and (c). Case (b) is already checked above. // allow cases (b) and (c). Case (b) is already checked above.
if (archives > 2) { if (num_archives > 2) {
vm_exit_during_initialization( vm_exit_during_initialization(
"Cannot have more than 2 archive files specified in the -XX:SharedArchiveFile option"); "Cannot have more than 2 archive files specified in the -XX:SharedArchiveFile option");
} }
if (archives == 1) {
char* base_archive_path = nullptr; if (num_archives == 1) {
const char* base_archive_path = nullptr;
bool success = bool success =
FileMapInfo::get_base_archive_name_from_header(SharedArchiveFile, &base_archive_path); FileMapInfo::get_base_archive_name_from_header(SharedArchiveFile, &base_archive_path);
if (!success) { if (!success) {
// If +AutoCreateSharedArchive and the specified shared archive does not exist, // If +AutoCreateSharedArchive and the specified shared archive does not exist,
// regenerate the dynamic archive base on default archive. // regenerate the dynamic archive base on default archive.
if (AutoCreateSharedArchive && !os::file_exists(SharedArchiveFile)) { if (AutoCreateSharedArchive && !os::file_exists(SharedArchiveFile)) {
enable_dumping_dynamic_archive(); enable_dumping_dynamic_archive(SharedArchiveFile);
ArchiveClassesAtExit = const_cast<char *>(SharedArchiveFile); FLAG_SET_ERGO(ArchiveClassesAtExit, SharedArchiveFile);
_static_archive_path = default_archive_path(); _input_static_archive_path = default_archive_path();
SharedArchiveFile = nullptr; FLAG_SET_ERGO(SharedArchiveFile, nullptr);
} else { } else {
if (AutoCreateSharedArchive) { if (AutoCreateSharedArchive) {
warning("-XX:+AutoCreateSharedArchive is unsupported when base CDS archive is not loaded. Run with -Xlog:cds for more info."); warning("-XX:+AutoCreateSharedArchive is unsupported when base CDS archive is not loaded. Run with -Xlog:cds for more info.");
AutoCreateSharedArchive = false; AutoCreateSharedArchive = false;
} }
log_error(cds)("Not a valid %s (%s)", new_aot_flags_used() ? "AOT cache" : "archive", SharedArchiveFile); log_error(cds)("Not a valid archive (%s)", SharedArchiveFile);
Arguments::no_shared_spaces("invalid archive"); Arguments::no_shared_spaces("invalid archive");
} }
} else if (base_archive_path == nullptr) { } else if (base_archive_path == nullptr) {
// User has specified a single archive, which is a static archive. // User has specified a single archive, which is a static archive.
_static_archive_path = const_cast<char *>(SharedArchiveFile); _input_static_archive_path = SharedArchiveFile;
} else { } else {
// User has specified a single archive, which is a dynamic archive. // User has specified a single archive, which is a dynamic archive.
_dynamic_archive_path = const_cast<char *>(SharedArchiveFile); _input_dynamic_archive_path = SharedArchiveFile;
_static_archive_path = base_archive_path; // has been c-heap allocated. _input_static_archive_path = base_archive_path; // has been c-heap allocated.
} }
} else { } else {
extract_shared_archive_paths((const char*)SharedArchiveFile, extract_archive_paths(SharedArchiveFile,
&_static_archive_path, &_dynamic_archive_path); &_input_static_archive_path, &_input_dynamic_archive_path);
if (_static_archive_path == nullptr) { if (_input_static_archive_path == nullptr) {
assert(_dynamic_archive_path == nullptr, "must be"); assert(_input_dynamic_archive_path == nullptr, "must be");
Arguments::no_shared_spaces("invalid archive"); Arguments::no_shared_spaces("invalid archive");
} }
} }
if (_dynamic_archive_path != nullptr) { if (_input_dynamic_archive_path != nullptr) {
// Check for case (c) // Check for case (c)
if (RecordDynamicDumpInfo) { if (RecordDynamicDumpInfo) {
vm_exit_during_initialization("-XX:+RecordDynamicDumpInfo is unsupported when a dynamic CDS archive is specified in -XX:SharedArchiveFile", vm_exit_during_initialization("-XX:+RecordDynamicDumpInfo is unsupported when a dynamic CDS archive is specified in -XX:SharedArchiveFile",
@ -353,14 +368,22 @@ bool CDSConfig::has_unsupported_runtime_module_options() {
return false; return false;
} }
#define CHECK_ALIAS(f) check_flag_alias(FLAG_IS_DEFAULT(f), #f) #define CHECK_NEW_FLAG(f) check_new_flag(FLAG_IS_DEFAULT(f), #f)
void CDSConfig::check_flag_alias(bool alias_is_default, const char* alias_name) { void CDSConfig::check_new_flag(bool new_flag_is_default, const char* new_flag_name) {
if (old_cds_flags_used() && !alias_is_default) { if (old_cds_flags_used() && !new_flag_is_default) {
vm_exit_during_initialization(err_msg("Option %s cannot be used at the same time with " vm_exit_during_initialization(err_msg("Option %s cannot be used at the same time with "
"-Xshare:on, -Xshare:auto, -Xshare:off, -Xshare:dump, " "-Xshare:on, -Xshare:auto, -Xshare:off, -Xshare:dump, "
"DumpLoadedClassList, SharedClassListFile, or SharedArchiveFile", "DumpLoadedClassList, SharedClassListFile, or SharedArchiveFile",
alias_name)); new_flag_name));
}
}
#define CHECK_SINGLE_PATH(f) check_flag_single_path(#f, f)
void CDSConfig::check_flag_single_path(const char* flag_name, const char* value) {
if (value != nullptr && num_archive_paths(value) != 1) {
vm_exit_during_initialization(err_msg("Option %s must specify a single file name", flag_name));
} }
} }
@ -371,9 +394,13 @@ void CDSConfig::check_aot_flags() {
_old_cds_flags_used = true; _old_cds_flags_used = true;
} }
CHECK_ALIAS(AOTCache); // "New" AOT flags must not be mixed with "classic" flags such as -Xshare:dump
CHECK_ALIAS(AOTConfiguration); CHECK_NEW_FLAG(AOTCache);
CHECK_ALIAS(AOTMode); CHECK_NEW_FLAG(AOTConfiguration);
CHECK_NEW_FLAG(AOTMode);
CHECK_SINGLE_PATH(AOTCache);
CHECK_SINGLE_PATH(AOTConfiguration);
if (FLAG_IS_DEFAULT(AOTCache) && FLAG_IS_DEFAULT(AOTConfiguration) && FLAG_IS_DEFAULT(AOTMode)) { if (FLAG_IS_DEFAULT(AOTCache) && FLAG_IS_DEFAULT(AOTConfiguration) && FLAG_IS_DEFAULT(AOTMode)) {
// AOTCache/AOTConfiguration/AOTMode not used. // AOTCache/AOTConfiguration/AOTMode not used.
@ -411,11 +438,6 @@ void CDSConfig::check_aotmode_auto_or_on() {
vm_exit_during_initialization("AOTConfiguration can only be used with -XX:AOTMode=record or -XX:AOTMode=create"); vm_exit_during_initialization("AOTConfiguration can only be used with -XX:AOTMode=record or -XX:AOTMode=create");
} }
if (!FLAG_IS_DEFAULT(AOTCache)) {
assert(FLAG_IS_DEFAULT(SharedArchiveFile), "already checked");
FLAG_SET_ERGO(SharedArchiveFile, AOTCache);
}
UseSharedSpaces = true; UseSharedSpaces = true;
if (FLAG_IS_DEFAULT(AOTMode) || (strcmp(AOTMode, "auto") == 0)) { if (FLAG_IS_DEFAULT(AOTMode) || (strcmp(AOTMode, "auto") == 0)) {
RequireSharedSpaces = false; RequireSharedSpaces = false;
@ -430,10 +452,6 @@ void CDSConfig::check_aotmode_record() {
vm_exit_during_initialization("AOTCache must not be specified when using -XX:AOTMode=record"); vm_exit_during_initialization("AOTCache must not be specified when using -XX:AOTMode=record");
} }
assert(FLAG_IS_DEFAULT(DumpLoadedClassList), "already checked");
assert(FLAG_IS_DEFAULT(SharedArchiveFile), "already checked");
FLAG_SET_ERGO(SharedArchiveFile, AOTConfiguration);
FLAG_SET_ERGO(DumpLoadedClassList, nullptr);
UseSharedSpaces = false; UseSharedSpaces = false;
RequireSharedSpaces = false; RequireSharedSpaces = false;
_is_dumping_static_archive = true; _is_dumping_static_archive = true;
@ -449,10 +467,7 @@ void CDSConfig::check_aotmode_create() {
vm_exit_during_initialization("AOTCache must be specified when using -XX:AOTMode=create"); vm_exit_during_initialization("AOTCache must be specified when using -XX:AOTMode=create");
} }
assert(FLAG_IS_DEFAULT(SharedArchiveFile), "already checked");
_is_dumping_final_static_archive = true; _is_dumping_final_static_archive = true;
FLAG_SET_ERGO(SharedArchiveFile, AOTConfiguration);
UseSharedSpaces = true; UseSharedSpaces = true;
RequireSharedSpaces = true; RequireSharedSpaces = true;
@ -463,7 +478,29 @@ void CDSConfig::check_aotmode_create() {
CDSConfig::enable_dumping_static_archive(); CDSConfig::enable_dumping_static_archive();
} }
void CDSConfig::ergo_init_aot_paths() {
assert(_cds_ergo_initialize_started, "sanity");
if (is_dumping_static_archive()) {
if (is_dumping_preimage_static_archive()) {
_output_archive_path = AOTConfiguration;
} else {
assert(is_dumping_final_static_archive(), "must be");
_input_static_archive_path = AOTConfiguration;
_output_archive_path = AOTCache;
}
} else if (is_using_archive()) {
if (FLAG_IS_DEFAULT(AOTCache)) {
// Only -XX:AOTMode={auto,on} is specified
_input_static_archive_path = default_archive_path();
} else {
_input_static_archive_path = AOTCache;
}
}
}
bool CDSConfig::check_vm_args_consistency(bool patch_mod_javabase, bool mode_flag_cmd_line) { bool CDSConfig::check_vm_args_consistency(bool patch_mod_javabase, bool mode_flag_cmd_line) {
assert(!_cds_ergo_initialize_started, "This is called earlier than CDSConfig::ergo_initialize()");
check_aot_flags(); check_aot_flags();
if (!FLAG_IS_DEFAULT(AOTMode)) { if (!FLAG_IS_DEFAULT(AOTMode)) {
@ -514,7 +551,7 @@ bool CDSConfig::check_vm_args_consistency(bool patch_mod_javabase, bool mode_fla
if (ArchiveClassesAtExit == nullptr && !RecordDynamicDumpInfo) { if (ArchiveClassesAtExit == nullptr && !RecordDynamicDumpInfo) {
disable_dumping_dynamic_archive(); disable_dumping_dynamic_archive();
} else { } else {
enable_dumping_dynamic_archive(); enable_dumping_dynamic_archive(ArchiveClassesAtExit);
} }
if (AutoCreateSharedArchive) { if (AutoCreateSharedArchive) {
@ -546,6 +583,34 @@ bool CDSConfig::check_vm_args_consistency(bool patch_mod_javabase, bool mode_fla
return true; return true;
} }
void CDSConfig::prepare_for_dumping() {
assert(CDSConfig::is_dumping_archive(), "sanity");
if (is_dumping_dynamic_archive() && !is_using_archive()) {
assert(!is_dumping_static_archive(), "cannot be dumping both static and dynamic archives");
// This could happen if SharedArchiveFile has failed to load:
// - -Xshare:off was specified
// - SharedArchiveFile points to an non-existent file.
// - SharedArchiveFile points to an archive that has failed CRC check
// - SharedArchiveFile is not specified and the VM doesn't have a compatible default archive
#define __THEMSG " is unsupported when base CDS archive is not loaded. Run with -Xlog:cds for more info."
if (RecordDynamicDumpInfo) {
log_error(cds)("-XX:+RecordDynamicDumpInfo%s", __THEMSG);
MetaspaceShared::unrecoverable_loading_error();
} else {
assert(ArchiveClassesAtExit != nullptr, "sanity");
log_warning(cds)("-XX:ArchiveClassesAtExit" __THEMSG);
}
#undef __THEMSG
disable_dumping_dynamic_archive();
return;
}
check_unsupported_dumping_module_options();
}
bool CDSConfig::is_dumping_classic_static_archive() { bool CDSConfig::is_dumping_classic_static_archive() {
return _is_dumping_static_archive && return _is_dumping_static_archive &&
!is_dumping_preimage_static_archive() && !is_dumping_preimage_static_archive() &&
@ -560,6 +625,18 @@ bool CDSConfig::is_dumping_final_static_archive() {
return _is_dumping_final_static_archive; return _is_dumping_final_static_archive;
} }
void CDSConfig::enable_dumping_dynamic_archive(const char* output_path) {
_is_dumping_dynamic_archive = true;
if (output_path == nullptr) {
// output_path can be null when the VM is started with -XX:+RecordDynamicDumpInfo
// in anticipation of "jcmd VM.cds dynamic_dump", which will provide the actual
// output path.
_output_archive_path = nullptr;
} else {
_output_archive_path = os::strdup_check_oom(output_path, mtArguments);
}
}
bool CDSConfig::allow_only_single_java_thread() { bool CDSConfig::allow_only_single_java_thread() {
// See comments in JVM_StartThread() // See comments in JVM_StartThread()
return is_dumping_classic_static_archive() || is_dumping_final_static_archive(); return is_dumping_classic_static_archive() || is_dumping_final_static_archive();

View File

@ -42,9 +42,10 @@ class CDSConfig : public AllStatic {
static bool _is_using_full_module_graph; static bool _is_using_full_module_graph;
static bool _has_aot_linked_classes; static bool _has_aot_linked_classes;
static char* _default_archive_path; const static char* _default_archive_path;
static char* _static_archive_path; const static char* _input_static_archive_path;
static char* _dynamic_archive_path; const static char* _input_dynamic_archive_path;
const static char* _output_archive_path;
static bool _old_cds_flags_used; static bool _old_cds_flags_used;
static bool _new_aot_flags_used; static bool _new_aot_flags_used;
@ -53,17 +54,24 @@ class CDSConfig : public AllStatic {
static JavaThread* _dumper_thread; static JavaThread* _dumper_thread;
#endif #endif
static void extract_shared_archive_paths(const char* archive_path, static void extract_archive_paths(const char* archive_path,
char** base_archive_path, const char** base_archive_path,
char** top_archive_path); const char** top_archive_path);
static void init_shared_archive_paths(); static int num_archive_paths(const char* path_spec);
static void check_flag_single_path(const char* flag_name, const char* value);
static void check_flag_alias(bool alias_is_default, const char* alias_name); // Checks before Arguments::apply_ergo()
static void check_new_flag(bool new_flag_is_default, const char* new_flag_name);
static void check_aot_flags(); static void check_aot_flags();
static void check_aotmode_off(); static void check_aotmode_off();
static void check_aotmode_auto_or_on(); static void check_aotmode_auto_or_on();
static void check_aotmode_record(); static void check_aotmode_record();
static void check_aotmode_create(); static void check_aotmode_create();
static void check_unsupported_dumping_module_options();
// Called after Arguments::apply_ergo() has started
static void ergo_init_classic_archive_paths();
static void ergo_init_aot_paths();
public: public:
// Used by jdk.internal.misc.CDS.getCDSConfigStatus(); // Used by jdk.internal.misc.CDS.getCDSConfigStatus();
@ -76,24 +84,25 @@ public:
static int get_status() NOT_CDS_RETURN_(0); static int get_status() NOT_CDS_RETURN_(0);
// Initialization and command-line checking // Initialization and command-line checking
static void initialize() NOT_CDS_RETURN; static void ergo_initialize() NOT_CDS_RETURN;
static void set_old_cds_flags_used() { CDS_ONLY(_old_cds_flags_used = true); } static void set_old_cds_flags_used() { CDS_ONLY(_old_cds_flags_used = true); }
static bool old_cds_flags_used() { return CDS_ONLY(_old_cds_flags_used) NOT_CDS(false); } static bool old_cds_flags_used() { return CDS_ONLY(_old_cds_flags_used) NOT_CDS(false); }
static bool new_aot_flags_used() { return CDS_ONLY(_new_aot_flags_used) NOT_CDS(false); } static bool new_aot_flags_used() { return CDS_ONLY(_new_aot_flags_used) NOT_CDS(false); }
static void check_internal_module_property(const char* key, const char* value) NOT_CDS_RETURN; static void check_internal_module_property(const char* key, const char* value) NOT_CDS_RETURN;
static void check_incompatible_property(const char* key, const char* value) NOT_CDS_RETURN; static void check_incompatible_property(const char* key, const char* value) NOT_CDS_RETURN;
static void check_unsupported_dumping_module_options() NOT_CDS_RETURN;
static bool has_unsupported_runtime_module_options() NOT_CDS_RETURN_(false); static bool has_unsupported_runtime_module_options() NOT_CDS_RETURN_(false);
static bool check_vm_args_consistency(bool patch_mod_javabase, bool mode_flag_cmd_line) NOT_CDS_RETURN_(true); static bool check_vm_args_consistency(bool patch_mod_javabase, bool mode_flag_cmd_line) NOT_CDS_RETURN_(true);
static const char* type_of_archive_being_loaded(); static const char* type_of_archive_being_loaded();
static const char* type_of_archive_being_written(); static const char* type_of_archive_being_written();
static void prepare_for_dumping();
// --- Basic CDS features // --- Basic CDS features
// archive(s) in general // archive(s) in general
static bool is_dumping_archive() { return is_dumping_static_archive() || is_dumping_dynamic_archive(); } static bool is_dumping_archive() { return is_dumping_static_archive() || is_dumping_dynamic_archive(); }
// input archive(s)
static bool is_using_archive() NOT_CDS_RETURN_(false); static bool is_using_archive() NOT_CDS_RETURN_(false);
static int num_archives(const char* archive_path) NOT_CDS_RETURN_(0);
// static_archive // static_archive
static bool is_dumping_static_archive() { return CDS_ONLY(_is_dumping_static_archive) NOT_CDS(false); } static bool is_dumping_static_archive() { return CDS_ONLY(_is_dumping_static_archive) NOT_CDS(false); }
@ -125,7 +134,7 @@ public:
// dynamic_archive // dynamic_archive
static bool is_dumping_dynamic_archive() { return CDS_ONLY(_is_dumping_dynamic_archive) NOT_CDS(false); } static bool is_dumping_dynamic_archive() { return CDS_ONLY(_is_dumping_dynamic_archive) NOT_CDS(false); }
static void enable_dumping_dynamic_archive() { CDS_ONLY(_is_dumping_dynamic_archive = true); } static void enable_dumping_dynamic_archive(const char* output_path) NOT_CDS_RETURN;
static void disable_dumping_dynamic_archive() { CDS_ONLY(_is_dumping_dynamic_archive = false); } static void disable_dumping_dynamic_archive() { CDS_ONLY(_is_dumping_dynamic_archive = false); }
// Misc CDS features // Misc CDS features
@ -147,12 +156,11 @@ public:
// archive_path // archive_path
// Points to the classes.jsa in $JAVA_HOME // Points to the classes.jsa in $JAVA_HOME (could be input or output)
static char* default_archive_path() NOT_CDS_RETURN_(nullptr); static const char* default_archive_path() NOT_CDS_RETURN_(nullptr);
// The actual static archive (if any) selected at runtime static const char* input_static_archive_path() { return CDS_ONLY(_input_static_archive_path) NOT_CDS(nullptr); }
static const char* static_archive_path() { return CDS_ONLY(_static_archive_path) NOT_CDS(nullptr); } static const char* input_dynamic_archive_path() { return CDS_ONLY(_input_dynamic_archive_path) NOT_CDS(nullptr); }
// The actual dynamic archive (if any) selected at runtime static const char* output_archive_path() { return CDS_ONLY(_output_archive_path) NOT_CDS(nullptr); }
static const char* dynamic_archive_path() { return CDS_ONLY(_dynamic_archive_path) NOT_CDS(nullptr); }
// --- Archived java objects // --- Archived java objects

View File

@ -97,8 +97,6 @@ public:
void gather_array_klasses(); void gather_array_klasses();
public: public:
DynamicArchiveBuilder() : ArchiveBuilder() { }
// Do this before and after the archive dump to see if any corruption // Do this before and after the archive dump to see if any corruption
// is caused by dynamic dumping. // is caused by dynamic dumping.
void verify_universe(const char* info) { void verify_universe(const char* info) {
@ -348,7 +346,7 @@ void DynamicArchiveBuilder::write_archive(char* serialized_data, AOTClassLocatio
FileMapInfo* dynamic_info = FileMapInfo::dynamic_info(); FileMapInfo* dynamic_info = FileMapInfo::dynamic_info();
assert(dynamic_info != nullptr, "Sanity"); assert(dynamic_info != nullptr, "Sanity");
dynamic_info->open_for_write(); dynamic_info->open_as_output();
ArchiveHeapInfo no_heap_for_dynamic_dump; ArchiveHeapInfo no_heap_for_dynamic_dump;
ArchiveBuilder::write_archive(dynamic_info, &no_heap_for_dynamic_dump); ArchiveBuilder::write_archive(dynamic_info, &no_heap_for_dynamic_dump);
@ -476,27 +474,6 @@ int DynamicArchive::num_array_klasses() {
return _array_klasses != nullptr ? _array_klasses->length() : 0; return _array_klasses != nullptr ? _array_klasses->length() : 0;
} }
void DynamicArchive::check_for_dynamic_dump() {
if (CDSConfig::is_dumping_dynamic_archive() && !CDSConfig::is_using_archive()) {
// This could happen if SharedArchiveFile has failed to load:
// - -Xshare:off was specified
// - SharedArchiveFile points to an non-existent file.
// - SharedArchiveFile points to an archive that has failed CRC check
// - SharedArchiveFile is not specified and the VM doesn't have a compatible default archive
#define __THEMSG " is unsupported when base CDS archive is not loaded. Run with -Xlog:cds for more info."
if (RecordDynamicDumpInfo) {
log_error(cds)("-XX:+RecordDynamicDumpInfo%s", __THEMSG);
MetaspaceShared::unrecoverable_loading_error();
} else {
assert(ArchiveClassesAtExit != nullptr, "sanity");
log_warning(cds)("-XX:ArchiveClassesAtExit" __THEMSG);
}
#undef __THEMSG
CDSConfig::disable_dumping_dynamic_archive();
}
}
void DynamicArchive::dump_impl(bool jcmd_request, const char* archive_name, TRAPS) { void DynamicArchive::dump_impl(bool jcmd_request, const char* archive_name, TRAPS) {
MetaspaceShared::link_shared_classes(CHECK); MetaspaceShared::link_shared_classes(CHECK);
if (!jcmd_request && CDSConfig::is_dumping_regenerated_lambdaform_invokers()) { if (!jcmd_request && CDSConfig::is_dumping_regenerated_lambdaform_invokers()) {
@ -507,11 +484,12 @@ void DynamicArchive::dump_impl(bool jcmd_request, const char* archive_name, TRAP
VMThread::execute(&op); VMThread::execute(&op);
} }
void DynamicArchive::dump_at_exit(JavaThread* current, const char* archive_name) { void DynamicArchive::dump_at_exit(JavaThread* current) {
ExceptionMark em(current); ExceptionMark em(current);
ResourceMark rm(current); ResourceMark rm(current);
CDSConfig::DumperThreadMark dumper_thread_mark(current); CDSConfig::DumperThreadMark dumper_thread_mark(current);
const char* archive_name = CDSConfig::output_archive_path();
if (!CDSConfig::is_dumping_dynamic_archive() || archive_name == nullptr) { if (!CDSConfig::is_dumping_dynamic_archive() || archive_name == nullptr) {
return; return;
} }

View File

@ -63,9 +63,8 @@ private:
static GrowableArray<ObjArrayKlass*>* _array_klasses; static GrowableArray<ObjArrayKlass*>* _array_klasses;
static Array<ObjArrayKlass*>* _dynamic_archive_array_klasses; static Array<ObjArrayKlass*>* _dynamic_archive_array_klasses;
public: public:
static void check_for_dynamic_dump();
static void dump_for_jcmd(const char* archive_name, TRAPS); static void dump_for_jcmd(const char* archive_name, TRAPS);
static void dump_at_exit(JavaThread* current, const char* archive_name); static void dump_at_exit(JavaThread* current);
static void dump_impl(bool jcmd_request, const char* archive_name, TRAPS); static void dump_impl(bool jcmd_request, const char* archive_name, TRAPS);
static bool is_mapped() { return FileMapInfo::dynamic_info() != nullptr; } static bool is_mapped() { return FileMapInfo::dynamic_info() != nullptr; }
static bool validate(FileMapInfo* dynamic_info); static bool validate(FileMapInfo* dynamic_info);

View File

@ -173,7 +173,7 @@ void FileMapInfo::populate_header(size_t core_region_alignment) {
header_size = c_header_size; header_size = c_header_size;
const char* default_base_archive_name = CDSConfig::default_archive_path(); const char* default_base_archive_name = CDSConfig::default_archive_path();
const char* current_base_archive_name = CDSConfig::static_archive_path(); const char* current_base_archive_name = CDSConfig::input_static_archive_path();
if (!os::same_files(current_base_archive_name, default_base_archive_name)) { if (!os::same_files(current_base_archive_name, default_base_archive_name)) {
base_archive_name_size = strlen(current_base_archive_name) + 1; base_archive_name_size = strlen(current_base_archive_name) + 1;
header_size += base_archive_name_size; header_size += base_archive_name_size;
@ -209,7 +209,7 @@ void FileMapHeader::populate(FileMapInfo *info, size_t core_region_alignment,
if (!info->is_static() && base_archive_name_size != 0) { if (!info->is_static() && base_archive_name_size != 0) {
// copy base archive name // copy base archive name
copy_base_archive_name(CDSConfig::static_archive_path()); copy_base_archive_name(CDSConfig::input_static_archive_path());
} }
_core_region_alignment = core_region_alignment; _core_region_alignment = core_region_alignment;
_obj_alignment = ObjectAlignmentInBytes; _obj_alignment = ObjectAlignmentInBytes;
@ -563,7 +563,7 @@ public:
// true && (*base_archive_name) != nullptr: // true && (*base_archive_name) != nullptr:
// <archive_name> is a valid dynamic archive. // <archive_name> is a valid dynamic archive.
bool FileMapInfo::get_base_archive_name_from_header(const char* archive_name, bool FileMapInfo::get_base_archive_name_from_header(const char* archive_name,
char** base_archive_name) { const char** base_archive_name) {
FileHeaderHelper file_helper(archive_name, false); FileHeaderHelper file_helper(archive_name, false);
*base_archive_name = nullptr; *base_archive_name = nullptr;
@ -619,7 +619,7 @@ bool FileMapInfo::init_from_file(int fd) {
// Good // Good
} else { } else {
if (CDSConfig::new_aot_flags_used()) { if (CDSConfig::new_aot_flags_used()) {
log_warning(cds)("Not a valid %s %s", file_type, _full_path); log_warning(cds)("Not a valid %s (%s)", file_type, _full_path);
} else { } else {
log_warning(cds)("Not a base shared archive: %s", _full_path); log_warning(cds)("Not a base shared archive: %s", _full_path);
} }
@ -729,7 +729,7 @@ bool FileMapInfo::open_for_read() {
// Write the FileMapInfo information to the file. // Write the FileMapInfo information to the file.
void FileMapInfo::open_for_write() { void FileMapInfo::open_as_output() {
LogMessage(cds) msg; LogMessage(cds) msg;
if (msg.is_info()) { if (msg.is_info()) {
if (CDSConfig::is_dumping_preimage_static_archive()) { if (CDSConfig::is_dumping_preimage_static_archive()) {
@ -1759,7 +1759,7 @@ bool FileMapInfo::_memory_mapping_failed = false;
// [1] validate_header() - done here. // [1] validate_header() - done here.
// [2] validate_shared_path_table - this is done later, because the table is in the RO // [2] validate_shared_path_table - this is done later, because the table is in the RO
// region of the archive, which is not mapped yet. // region of the archive, which is not mapped yet.
bool FileMapInfo::initialize() { bool FileMapInfo::open_as_input() {
assert(CDSConfig::is_using_archive(), "UseSharedSpaces expected."); assert(CDSConfig::is_using_archive(), "UseSharedSpaces expected.");
assert(Arguments::has_jimage(), "The shared archive file cannot be used with an exploded module build."); assert(Arguments::has_jimage(), "The shared archive file cannot be used with an exploded module build.");
@ -1774,13 +1774,12 @@ bool FileMapInfo::initialize() {
if (!open_for_read() || !init_from_file(_fd) || !validate_header()) { if (!open_for_read() || !init_from_file(_fd) || !validate_header()) {
if (_is_static) { if (_is_static) {
log_info(cds)("Initialize static archive failed."); log_info(cds)("Loading static archive failed.");
return false; return false;
} else { } else {
log_info(cds)("Initialize dynamic archive failed."); log_info(cds)("Loading dynamic archive failed.");
if (AutoCreateSharedArchive) { if (AutoCreateSharedArchive) {
CDSConfig::enable_dumping_dynamic_archive(); CDSConfig::enable_dumping_dynamic_archive(_full_path);
ArchiveClassesAtExit = CDSConfig::dynamic_archive_path();
} }
return false; return false;
} }

View File

@ -268,7 +268,7 @@ private:
public: public:
FileMapHeader *header() const { return _header; } FileMapHeader *header() const { return _header; }
static bool get_base_archive_name_from_header(const char* archive_name, static bool get_base_archive_name_from_header(const char* archive_name,
char** base_archive_name); const char** base_archive_name);
static bool is_preimage_static_archive(const char* file); static bool is_preimage_static_archive(const char* file);
bool init_from_file(int fd); bool init_from_file(int fd);
@ -346,9 +346,8 @@ public:
static void assert_mark(bool check); static void assert_mark(bool check);
// File manipulation. // File manipulation.
bool initialize() NOT_CDS_RETURN_(false); bool open_as_input() NOT_CDS_RETURN_(false);
bool open_for_read(); void open_as_output();
void open_for_write();
void write_header(); void write_header();
void write_region(int region, char* base, size_t size, void write_region(int region, char* base, size_t size,
bool read_only, bool allow_exec); bool read_only, bool allow_exec);
@ -425,6 +424,7 @@ public:
} }
private: private:
bool open_for_read();
void seek_to_position(size_t pos); void seek_to_position(size_t pos);
bool map_heap_region_impl() NOT_CDS_JAVA_HEAP_RETURN_(false); bool map_heap_region_impl() NOT_CDS_JAVA_HEAP_RETURN_(false);
void dealloc_heap_region() NOT_CDS_JAVA_HEAP_RETURN; void dealloc_heap_region() NOT_CDS_JAVA_HEAP_RETURN;

View File

@ -678,14 +678,11 @@ void VM_PopulateDumpSharedSpace::doit() {
CppVtables::zero_archived_vtables(); CppVtables::zero_archived_vtables();
// Write the archive file // Write the archive file
const char* static_archive;
if (CDSConfig::is_dumping_final_static_archive()) { if (CDSConfig::is_dumping_final_static_archive()) {
static_archive = AOTCache; FileMapInfo::free_current_info(); // FIXME: should not free current info
FileMapInfo::free_current_info();
} else {
static_archive = CDSConfig::static_archive_path();
} }
assert(static_archive != nullptr, "SharedArchiveFile not set?"); const char* static_archive = CDSConfig::output_archive_path();
assert(static_archive != nullptr, "sanity");
_map_info = new FileMapInfo(static_archive, true); _map_info = new FileMapInfo(static_archive, true);
_map_info->populate_header(MetaspaceShared::core_region_alignment()); _map_info->populate_header(MetaspaceShared::core_region_alignment());
_map_info->set_early_serialized_data(early_serialized_data); _map_info->set_early_serialized_data(early_serialized_data);
@ -789,11 +786,6 @@ void MetaspaceShared::link_shared_classes(TRAPS) {
} }
} }
void MetaspaceShared::prepare_for_dumping() {
assert(CDSConfig::is_dumping_archive(), "sanity");
CDSConfig::check_unsupported_dumping_module_options();
}
// Preload classes from a list, populate the shared spaces and dump to a // Preload classes from a list, populate the shared spaces and dump to a
// file. // file.
void MetaspaceShared::preload_and_dump(TRAPS) { void MetaspaceShared::preload_and_dump(TRAPS) {
@ -1023,7 +1015,7 @@ bool MetaspaceShared::write_static_archive(ArchiveBuilder* builder, FileMapInfo*
// without runtime relocation. // without runtime relocation.
builder->relocate_to_requested(); builder->relocate_to_requested();
map_info->open_for_write(); map_info->open_as_output();
if (!map_info->is_open()) { if (!map_info->is_open()) {
return false; return false;
} }
@ -1214,10 +1206,10 @@ void MetaspaceShared::initialize_runtime_shared_and_meta_spaces() {
} }
FileMapInfo* MetaspaceShared::open_static_archive() { FileMapInfo* MetaspaceShared::open_static_archive() {
const char* static_archive = CDSConfig::static_archive_path(); const char* static_archive = CDSConfig::input_static_archive_path();
assert(static_archive != nullptr, "sanity"); assert(static_archive != nullptr, "sanity");
FileMapInfo* mapinfo = new FileMapInfo(static_archive, true); FileMapInfo* mapinfo = new FileMapInfo(static_archive, true);
if (!mapinfo->initialize()) { if (!mapinfo->open_as_input()) {
delete(mapinfo); delete(mapinfo);
return nullptr; return nullptr;
} }
@ -1228,13 +1220,13 @@ FileMapInfo* MetaspaceShared::open_dynamic_archive() {
if (CDSConfig::is_dumping_dynamic_archive()) { if (CDSConfig::is_dumping_dynamic_archive()) {
return nullptr; return nullptr;
} }
const char* dynamic_archive = CDSConfig::dynamic_archive_path(); const char* dynamic_archive = CDSConfig::input_dynamic_archive_path();
if (dynamic_archive == nullptr) { if (dynamic_archive == nullptr) {
return nullptr; return nullptr;
} }
FileMapInfo* mapinfo = new FileMapInfo(dynamic_archive, false); FileMapInfo* mapinfo = new FileMapInfo(dynamic_archive, false);
if (!mapinfo->initialize()) { if (!mapinfo->open_as_input()) {
delete(mapinfo); delete(mapinfo);
if (RequireSharedSpaces) { if (RequireSharedSpaces) {
MetaspaceShared::unrecoverable_loading_error("Failed to initialize dynamic archive"); MetaspaceShared::unrecoverable_loading_error("Failed to initialize dynamic archive");
@ -1817,7 +1809,7 @@ void MetaspaceShared::initialize_shared_spaces() {
if (PrintSharedArchiveAndExit) { if (PrintSharedArchiveAndExit) {
// Print archive names // Print archive names
if (dynamic_mapinfo != nullptr) { if (dynamic_mapinfo != nullptr) {
tty->print_cr("\n\nBase archive name: %s", CDSConfig::static_archive_path()); tty->print_cr("\n\nBase archive name: %s", CDSConfig::input_static_archive_path());
tty->print_cr("Base archive version %d", static_mapinfo->version()); tty->print_cr("Base archive version %d", static_mapinfo->version());
} else { } else {
tty->print_cr("Static archive name: %s", static_mapinfo->full_path()); tty->print_cr("Static archive name: %s", static_mapinfo->full_path());

View File

@ -71,7 +71,6 @@ class MetaspaceShared : AllStatic {
n_regions = 4 // total number of regions n_regions = 4 // total number of regions
}; };
static void prepare_for_dumping() NOT_CDS_RETURN;
static void preload_and_dump(TRAPS) NOT_CDS_RETURN; static void preload_and_dump(TRAPS) NOT_CDS_RETURN;
#ifdef _LP64 #ifdef _LP64
static void adjust_heap_sizes_for_dumping() NOT_CDS_JAVA_HEAP_RETURN; static void adjust_heap_sizes_for_dumping() NOT_CDS_JAVA_HEAP_RETURN;

View File

@ -897,14 +897,13 @@ jint universe_init() {
ClassLoaderData::init_null_class_loader_data(); ClassLoaderData::init_null_class_loader_data();
#if INCLUDE_CDS #if INCLUDE_CDS
DynamicArchive::check_for_dynamic_dump();
if (CDSConfig::is_using_archive()) { if (CDSConfig::is_using_archive()) {
// Read the data structures supporting the shared spaces (shared // Read the data structures supporting the shared spaces (shared
// system dictionary, symbol table, etc.) // system dictionary, symbol table, etc.)
MetaspaceShared::initialize_shared_spaces(); MetaspaceShared::initialize_shared_spaces();
} }
if (CDSConfig::is_dumping_archive()) { if (CDSConfig::is_dumping_archive()) {
MetaspaceShared::prepare_for_dumping(); CDSConfig::prepare_for_dumping();
} }
#endif #endif

View File

@ -3708,7 +3708,7 @@ jint Arguments::apply_ergo() {
CompressedKlassPointers::pre_initialize(); CompressedKlassPointers::pre_initialize();
} }
CDSConfig::initialize(); CDSConfig::ergo_initialize();
// Initialize Metaspace flags and alignments // Initialize Metaspace flags and alignments
Metaspace::ergo_initialize(); Metaspace::ergo_initialize();

View File

@ -426,11 +426,10 @@ void before_exit(JavaThread* thread, bool halt) {
#if INCLUDE_CDS #if INCLUDE_CDS
// Dynamic CDS dumping must happen whilst we can still reliably // Dynamic CDS dumping must happen whilst we can still reliably
// run Java code. // run Java code.
DynamicArchive::dump_at_exit(thread, ArchiveClassesAtExit); DynamicArchive::dump_at_exit(thread);
assert(!thread->has_pending_exception(), "must be"); assert(!thread->has_pending_exception(), "must be");
#endif #endif
// Actual shutdown logic begins here. // Actual shutdown logic begins here.
#if INCLUDE_JVMCI #if INCLUDE_JVMCI

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -265,7 +265,7 @@ bool read_string(struct ps_prochandle* ph, uintptr_t addr, char* buf, size_t siz
#ifdef LINUX #ifdef LINUX
// mangled name of CDSConfig::_static_archive_path // mangled name of CDSConfig::_static_archive_path
#define SHARED_ARCHIVE_PATH_SYM "_ZN9CDSConfig20_static_archive_pathE" #define SHARED_ARCHIVE_PATH_SYM "_ZN9CDSConfig26_input_static_archive_pathE"
#define USE_SHARED_SPACES_SYM "UseSharedSpaces" #define USE_SHARED_SPACES_SYM "UseSharedSpaces"
#define SHARED_BASE_ADDRESS_SYM "SharedBaseAddress" #define SHARED_BASE_ADDRESS_SYM "SharedBaseAddress"
#define LIBJVM_NAME "/libjvm.so" #define LIBJVM_NAME "/libjvm.so"
@ -273,7 +273,7 @@ bool read_string(struct ps_prochandle* ph, uintptr_t addr, char* buf, size_t siz
#ifdef __APPLE__ #ifdef __APPLE__
// mangled name of CDSConfig::_static_archive_path // mangled name of CDSConfig::_static_archive_path
#define SHARED_ARCHIVE_PATH_SYM "__ZN9CDSConfig20_static_archive_pathE" #define SHARED_ARCHIVE_PATH_SYM "__ZN9CDSConfig26_input_static_archive_pathE"
#define USE_SHARED_SPACES_SYM "_UseSharedSpaces" #define USE_SHARED_SPACES_SYM "_UseSharedSpaces"
#define SHARED_BASE_ADDRESS_SYM "_SharedBaseAddress" #define SHARED_BASE_ADDRESS_SYM "_SharedBaseAddress"
#define LIBJVM_NAME "/libjvm.dylib" #define LIBJVM_NAME "/libjvm.dylib"

View File

@ -26,12 +26,14 @@
* @test * @test
* @summary "AOT" aliases for traditional CDS command-line options * @summary "AOT" aliases for traditional CDS command-line options
* @requires vm.cds * @requires vm.cds
* @requires vm.flagless
* @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds/test-classes * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds/test-classes
* @build Hello * @build Hello
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar hello.jar Hello * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar hello.jar Hello
* @run driver AOTFlags * @run driver AOTFlags
*/ */
import java.io.File;
import jdk.test.lib.cds.CDSTestUtils; import jdk.test.lib.cds.CDSTestUtils;
import jdk.test.lib.helpers.ClassFileInstaller; import jdk.test.lib.helpers.ClassFileInstaller;
import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.OutputAnalyzer;
@ -298,6 +300,60 @@ public class AOTFlags {
"specified when the AOTConfiguration file was recorded"); "specified when the AOTConfiguration file was recorded");
out.shouldContain("Unable to use create AOT cache"); out.shouldContain("Unable to use create AOT cache");
out.shouldHaveExitValue(1); out.shouldHaveExitValue(1);
//----------------------------------------------------------------------
printTestCase("Cannot use multiple paths in AOTConfiguration");
pb = ProcessTools.createLimitedTestJavaProcessBuilder(
"-XX:AOTMode=record",
"-XX:AOTConfiguration=" + aotConfigFile + File.pathSeparator + "dummy",
"-cp", "noSuchJar.jar");
out = CDSTestUtils.executeAndLog(pb, "neg");
out.shouldContain("Option AOTConfiguration must specify a single file name");
out.shouldHaveExitValue(1);
//----------------------------------------------------------------------
printTestCase("Cannot use multiple paths in AOTCache");
pb = ProcessTools.createLimitedTestJavaProcessBuilder(
"-XX:AOTMode=create",
"-XX:AOTConfiguration=" + aotConfigFile,
"-XX:AOTCache=" + aotCacheFile + File.pathSeparator + "dummy",
"-cp", "noSuchJar.jar");
out = CDSTestUtils.executeAndLog(pb, "neg");
out.shouldContain("Option AOTCache must specify a single file name");
out.shouldHaveExitValue(1);
//----------------------------------------------------------------------
printTestCase("Cannot use a dynamic CDS archive for -XX:AOTCache");
String staticArchive = "static.jsa";
String dynamicArchive = "dynamic.jsa";
pb = ProcessTools.createLimitedTestJavaProcessBuilder(
"-Xshare:dump",
"-XX:SharedArchiveFile=" + staticArchive);
out = CDSTestUtils.executeAndLog(pb, "static");
out.shouldHaveExitValue(0);
pb = ProcessTools.createLimitedTestJavaProcessBuilder(
"-XX:SharedArchiveFile=" + staticArchive,
"-XX:ArchiveClassesAtExit=" + dynamicArchive,
"--version");
out = CDSTestUtils.executeAndLog(pb, "dynamic");
out.shouldHaveExitValue(0);
pb = ProcessTools.createLimitedTestJavaProcessBuilder(
"-Xlog:cds",
"-XX:AOTMode=on",
"-XX:AOTCache=" + dynamicArchive,
"--version");
out = CDSTestUtils.executeAndLog(pb, "neg");
out.shouldContain("Unable to use AOT cache.");
out.shouldContain("Not a valid AOT cache (dynamic.jsa)");
out.shouldHaveExitValue(1);
} }
static int testNum = 0; static int testNum = 0;

View File

@ -337,7 +337,7 @@ public class TestAutoCreateSharedArchive extends DynamicArchiveTestBase {
.shouldContain(HELLO_WORLD) .shouldContain(HELLO_WORLD)
.shouldContain("The shared archive file version " + hex(version2) + " does not match the required version " + hex(currentCDSVersion)) .shouldContain("The shared archive file version " + hex(version2) + " does not match the required version " + hex(currentCDSVersion))
.shouldContain("The shared archive file has the wrong version") .shouldContain("The shared archive file has the wrong version")
.shouldContain("Initialize dynamic archive failed") .shouldContain("Loading dynamic archive failed")
.shouldContain("Dumping shared data to file"); .shouldContain("Dumping shared data to file");
}); });
ft2 = Files.getLastModifiedTime(Paths.get(modVersion)); ft2 = Files.getLastModifiedTime(Paths.get(modVersion));

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -112,7 +112,7 @@ public class TestAutoCreateSharedArchiveNoDefaultArchive {
"-version"); "-version");
TestCommon.executeAndLog(pb, "show-version") TestCommon.executeAndLog(pb, "show-version")
.shouldHaveExitValue(0) .shouldHaveExitValue(0)
.shouldContain("Initialize static archive failed") .shouldContain("Loading static archive failed")
.shouldContain("Unable to map shared spaces") .shouldContain("Unable to map shared spaces")
.shouldNotContain("sharing"); .shouldNotContain("sharing");
} }
@ -132,7 +132,7 @@ public class TestAutoCreateSharedArchiveNoDefaultArchive {
mainClass); mainClass);
TestCommon.executeAndLog(pb, "no-default-archive") TestCommon.executeAndLog(pb, "no-default-archive")
.shouldHaveExitValue(0) .shouldHaveExitValue(0)
.shouldContain("Initialize static archive failed") .shouldContain("Loading static archive failed")
.shouldContain("Unable to map shared spaces") .shouldContain("Unable to map shared spaces")
.shouldNotContain("Dumping shared data to file"); .shouldNotContain("Dumping shared data to file");
if (jsaFile.exists()) { if (jsaFile.exists()) {