8353597: Refactor handling VM options for AOT cache input and output
Reviewed-by: kvn, asmehra
This commit is contained in:
parent
4dc9e58906
commit
567c6885a3
@ -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();
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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());
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
|
@ -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"
|
||||||
|
@ -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;
|
||||||
|
@ -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));
|
||||||
|
@ -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()) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user