1 /* 2 * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "cds/archiveHeapLoader.hpp" 26 #include "cds/cdsConfig.hpp" 27 #include "cds/classListWriter.hpp" 28 #include "cds/filemap.hpp" 29 #include "cds/heapShared.hpp" 30 #include "classfile/classLoaderDataShared.hpp" 31 #include "classfile/moduleEntry.hpp" 32 #include "include/jvm_io.h" 33 #include "logging/log.hpp" 34 #include "memory/universe.hpp" 35 #include "runtime/arguments.hpp" 36 #include "runtime/globals_extension.hpp" 37 #include "runtime/java.hpp" 38 #include "runtime/vmThread.hpp" 39 #include "utilities/defaultStream.hpp" 40 #include "utilities/formatBuffer.hpp" 41 42 bool CDSConfig::_is_dumping_static_archive = false; 43 bool CDSConfig::_is_dumping_preimage_static_archive = false; 44 bool CDSConfig::_is_dumping_final_static_archive = false; 45 bool CDSConfig::_is_dumping_dynamic_archive = false; 46 bool CDSConfig::_is_using_optimized_module_handling = true; 47 bool CDSConfig::_is_dumping_full_module_graph = true; 48 bool CDSConfig::_is_using_full_module_graph = true; 49 bool CDSConfig::_has_aot_linked_classes = false; 50 bool CDSConfig::_has_archived_invokedynamic = false; 51 bool CDSConfig::_old_cds_flags_used = false; 52 bool CDSConfig::_new_aot_flags_used = false; 53 bool CDSConfig::_disable_heap_dumping = false; 54 55 char* CDSConfig::_default_archive_path = nullptr; 56 char* CDSConfig::_static_archive_path = nullptr; 57 char* CDSConfig::_dynamic_archive_path = nullptr; 58 59 JavaThread* CDSConfig::_dumper_thread = nullptr; 60 61 int CDSConfig::get_status() { 62 assert(Universe::is_fully_initialized(), "status is finalized only after Universe is initialized"); 63 return (is_dumping_archive() ? IS_DUMPING_ARCHIVE : 0) | 64 (is_dumping_static_archive() ? IS_DUMPING_STATIC_ARCHIVE : 0) | 65 (is_logging_lambda_form_invokers() ? IS_LOGGING_LAMBDA_FORM_INVOKERS : 0) | 66 (is_using_archive() ? IS_USING_ARCHIVE : 0); 67 } 68 69 void CDSConfig::initialize() { 70 if (is_dumping_static_archive() && !is_dumping_final_static_archive()) { 71 if (RequireSharedSpaces) { 72 warning("Cannot dump shared archive while using shared archive"); 73 } 74 UseSharedSpaces = false; 75 } 76 77 // Initialize shared archive paths which could include both base and dynamic archive paths 78 // This must be after set_ergonomics_flags() called so flag UseCompressedOops is set properly. 79 // 80 // UseSharedSpaces may be disabled if -XX:SharedArchiveFile is invalid. 81 if (is_dumping_static_archive() || is_using_archive()) { 82 init_shared_archive_paths(); 83 } 84 85 if (!is_dumping_heap()) { 86 _is_dumping_full_module_graph = false; 87 } 88 } 89 90 char* CDSConfig::default_archive_path() { 91 if (_default_archive_path == nullptr) { 92 char jvm_path[JVM_MAXPATHLEN]; 93 os::jvm_path(jvm_path, sizeof(jvm_path)); 94 char *end = strrchr(jvm_path, *os::file_separator()); 95 if (end != nullptr) *end = '\0'; 96 stringStream tmp; 97 tmp.print("%s%sclasses", jvm_path, os::file_separator()); 98 #ifdef _LP64 99 if (!UseCompressedOops) { 100 tmp.print_raw("_nocoops"); 101 } 102 if (UseCompactObjectHeaders) { 103 // Note that generation of xxx_coh.jsa variants require 104 // --enable-cds-archive-coh at build time 105 tmp.print_raw("_coh"); 106 } 107 #endif 108 tmp.print_raw(".jsa"); 109 _default_archive_path = os::strdup(tmp.base()); 110 } 111 return _default_archive_path; 112 } 113 114 int CDSConfig::num_archives(const char* archive_path) { 115 if (archive_path == nullptr) { 116 return 0; 117 } 118 int npaths = 1; 119 char* p = (char*)archive_path; 120 while (*p != '\0') { 121 if (*p == os::path_separator()[0]) { 122 npaths++; 123 } 124 p++; 125 } 126 return npaths; 127 } 128 129 void CDSConfig::extract_shared_archive_paths(const char* archive_path, 130 char** base_archive_path, 131 char** top_archive_path) { 132 char* begin_ptr = (char*)archive_path; 133 char* end_ptr = strchr((char*)archive_path, os::path_separator()[0]); 134 if (end_ptr == nullptr || end_ptr == begin_ptr) { 135 vm_exit_during_initialization("Base archive was not specified", archive_path); 136 } 137 size_t len = end_ptr - begin_ptr; 138 char* cur_path = NEW_C_HEAP_ARRAY(char, len + 1, mtInternal); 139 strncpy(cur_path, begin_ptr, len); 140 cur_path[len] = '\0'; 141 *base_archive_path = cur_path; 142 143 begin_ptr = ++end_ptr; 144 if (*begin_ptr == '\0') { 145 vm_exit_during_initialization("Top archive was not specified", archive_path); 146 } 147 end_ptr = strchr(begin_ptr, '\0'); 148 assert(end_ptr != nullptr, "sanity"); 149 len = end_ptr - begin_ptr; 150 cur_path = NEW_C_HEAP_ARRAY(char, len + 1, mtInternal); 151 strncpy(cur_path, begin_ptr, len + 1); 152 *top_archive_path = cur_path; 153 } 154 155 void CDSConfig::init_shared_archive_paths() { 156 if (ArchiveClassesAtExit != nullptr) { 157 assert(!RecordDynamicDumpInfo, "already checked"); 158 if (is_dumping_static_archive()) { 159 vm_exit_during_initialization("-XX:ArchiveClassesAtExit cannot be used with -Xshare:dump"); 160 } 161 check_unsupported_dumping_module_options(); 162 163 if (os::same_files(default_archive_path(), ArchiveClassesAtExit)) { 164 vm_exit_during_initialization( 165 "Cannot specify the default CDS archive for -XX:ArchiveClassesAtExit", default_archive_path()); 166 } 167 } 168 169 if (SharedArchiveFile == nullptr) { 170 _static_archive_path = default_archive_path(); 171 } else { 172 int archives = num_archives(SharedArchiveFile); 173 assert(archives > 0, "must be"); 174 175 if (is_dumping_archive() && archives > 1) { 176 vm_exit_during_initialization( 177 "Cannot have more than 1 archive file specified in -XX:SharedArchiveFile during CDS dumping"); 178 } 179 180 if (is_dumping_static_archive()) { 181 assert(archives == 1, "must be"); 182 // Static dump is simple: only one archive is allowed in SharedArchiveFile. This file 183 // will be overwritten no matter regardless of its contents 184 _static_archive_path = os::strdup_check_oom(SharedArchiveFile, mtArguments); 185 } else { 186 // SharedArchiveFile may specify one or two files. In case (c), the path for base.jsa 187 // is read from top.jsa 188 // (a) 1 file: -XX:SharedArchiveFile=base.jsa 189 // (b) 2 files: -XX:SharedArchiveFile=base.jsa:top.jsa 190 // (c) 2 files: -XX:SharedArchiveFile=top.jsa 191 // 192 // However, if either RecordDynamicDumpInfo or ArchiveClassesAtExit is used, we do not 193 // allow cases (b) and (c). Case (b) is already checked above. 194 195 if (archives > 2) { 196 vm_exit_during_initialization( 197 "Cannot have more than 2 archive files specified in the -XX:SharedArchiveFile option"); 198 } 199 if (archives == 1) { 200 char* base_archive_path = nullptr; 201 bool success = 202 FileMapInfo::get_base_archive_name_from_header(SharedArchiveFile, &base_archive_path); 203 if (!success) { 204 // If +AutoCreateSharedArchive and the specified shared archive does not exist, 205 // regenerate the dynamic archive base on default archive. 206 if (AutoCreateSharedArchive && !os::file_exists(SharedArchiveFile)) { 207 enable_dumping_dynamic_archive(); 208 ArchiveClassesAtExit = const_cast<char *>(SharedArchiveFile); 209 _static_archive_path = default_archive_path(); 210 SharedArchiveFile = nullptr; 211 } else { 212 if (AutoCreateSharedArchive) { 213 warning("-XX:+AutoCreateSharedArchive is unsupported when base CDS archive is not loaded. Run with -Xlog:cds for more info."); 214 AutoCreateSharedArchive = false; 215 } 216 log_error(cds)("Not a valid %s (%s)", new_aot_flags_used() ? "AOT cache" : "archive", SharedArchiveFile); 217 Arguments::no_shared_spaces("invalid archive"); 218 } 219 } else if (base_archive_path == nullptr) { 220 // User has specified a single archive, which is a static archive. 221 _static_archive_path = const_cast<char *>(SharedArchiveFile); 222 } else { 223 // User has specified a single archive, which is a dynamic archive. 224 _dynamic_archive_path = const_cast<char *>(SharedArchiveFile); 225 _static_archive_path = base_archive_path; // has been c-heap allocated. 226 } 227 } else { 228 extract_shared_archive_paths((const char*)SharedArchiveFile, 229 &_static_archive_path, &_dynamic_archive_path); 230 if (_static_archive_path == nullptr) { 231 assert(_dynamic_archive_path == nullptr, "must be"); 232 Arguments::no_shared_spaces("invalid archive"); 233 } 234 } 235 236 if (_dynamic_archive_path != nullptr) { 237 // Check for case (c) 238 if (RecordDynamicDumpInfo) { 239 vm_exit_during_initialization("-XX:+RecordDynamicDumpInfo is unsupported when a dynamic CDS archive is specified in -XX:SharedArchiveFile", 240 SharedArchiveFile); 241 } 242 if (ArchiveClassesAtExit != nullptr) { 243 vm_exit_during_initialization("-XX:ArchiveClassesAtExit is unsupported when a dynamic CDS archive is specified in -XX:SharedArchiveFile", 244 SharedArchiveFile); 245 } 246 } 247 248 if (ArchiveClassesAtExit != nullptr && os::same_files(SharedArchiveFile, ArchiveClassesAtExit)) { 249 vm_exit_during_initialization( 250 "Cannot have the same archive file specified for -XX:SharedArchiveFile and -XX:ArchiveClassesAtExit", 251 SharedArchiveFile); 252 } 253 } 254 } 255 } 256 257 void CDSConfig::check_internal_module_property(const char* key, const char* value) { 258 if (Arguments::is_incompatible_cds_internal_module_property(key)) { 259 stop_using_optimized_module_handling(); 260 log_info(cds)("optimized module handling: disabled due to incompatible property: %s=%s", key, value); 261 } 262 } 263 264 void CDSConfig::check_incompatible_property(const char* key, const char* value) { 265 static const char* incompatible_properties[] = { 266 "java.system.class.loader", 267 "jdk.module.showModuleResolution", 268 "jdk.module.validation" 269 }; 270 271 for (const char* property : incompatible_properties) { 272 if (strcmp(key, property) == 0) { 273 stop_dumping_full_module_graph(); 274 stop_using_full_module_graph(); 275 log_info(cds)("full module graph: disabled due to incompatible property: %s=%s", key, value); 276 break; 277 } 278 } 279 280 } 281 282 // Returns any JVM command-line option, such as "--patch-module", that's not supported by CDS. 283 static const char* find_any_unsupported_module_option() { 284 // Note that arguments.cpp has translated the command-line options into properties. If we find an 285 // unsupported property, translate it back to its command-line option for better error reporting. 286 287 // The following properties are checked by Arguments::is_internal_module_property() and cannot be 288 // directly specified in the command-line. 289 static const char* unsupported_module_properties[] = { 290 "jdk.module.limitmods", 291 "jdk.module.upgrade.path", 292 "jdk.module.patch.0" 293 }; 294 static const char* unsupported_module_options[] = { 295 "--limit-modules", 296 "--upgrade-module-path", 297 "--patch-module" 298 }; 299 300 assert(ARRAY_SIZE(unsupported_module_properties) == ARRAY_SIZE(unsupported_module_options), "must be"); 301 SystemProperty* sp = Arguments::system_properties(); 302 while (sp != nullptr) { 303 for (uint i = 0; i < ARRAY_SIZE(unsupported_module_properties); i++) { 304 if (strcmp(sp->key(), unsupported_module_properties[i]) == 0) { 305 return unsupported_module_options[i]; 306 } 307 } 308 sp = sp->next(); 309 } 310 311 return nullptr; // not found 312 } 313 314 void CDSConfig::check_unsupported_dumping_module_options() { 315 assert(is_dumping_archive(), "this function is only used with CDS dump time"); 316 const char* option = find_any_unsupported_module_option(); 317 if (option != nullptr) { 318 vm_exit_during_initialization("Cannot use the following option when dumping the shared archive", option); 319 } 320 // Check for an exploded module build in use with -Xshare:dump. 321 if (!Arguments::has_jimage()) { 322 vm_exit_during_initialization("Dumping the shared archive is not supported with an exploded module build"); 323 } 324 } 325 326 bool CDSConfig::has_unsupported_runtime_module_options() { 327 assert(is_using_archive(), "this function is only used with -Xshare:{on,auto}"); 328 if (ArchiveClassesAtExit != nullptr) { 329 // dynamic dumping, just return false for now. 330 // check_unsupported_dumping_properties() will be called later to check the same set of 331 // properties, and will exit the VM with the correct error message if the unsupported properties 332 // are used. 333 return false; 334 } 335 const char* option = find_any_unsupported_module_option(); 336 if (option != nullptr) { 337 if (RequireSharedSpaces) { 338 warning("CDS is disabled when the %s option is specified.", option); 339 } else { 340 if (new_aot_flags_used()) { 341 log_warning(cds)("AOT cache is disabled when the %s option is specified.", option); 342 } else { 343 log_info(cds)("CDS is disabled when the %s option is specified.", option); 344 } 345 } 346 return true; 347 } 348 return false; 349 } 350 351 #define CHECK_ALIAS(f) check_flag_alias(FLAG_IS_DEFAULT(f), #f) 352 353 void CDSConfig::check_flag_alias(bool alias_is_default, const char* alias_name) { 354 if (old_cds_flags_used() && !alias_is_default) { 355 vm_exit_during_initialization(err_msg("Option %s cannot be used at the same time with " 356 "-Xshare:on, -Xshare:auto, -Xshare:off, -Xshare:dump, " 357 "DumpLoadedClassList, SharedClassListFile, or SharedArchiveFile", 358 alias_name)); 359 } 360 } 361 362 void CDSConfig::check_aot_flags() { 363 if (!FLAG_IS_DEFAULT(DumpLoadedClassList) || 364 !FLAG_IS_DEFAULT(SharedClassListFile) || 365 !FLAG_IS_DEFAULT(SharedArchiveFile)) { 366 _old_cds_flags_used = true; 367 } 368 369 CHECK_ALIAS(AOTCache); 370 CHECK_ALIAS(AOTConfiguration); 371 CHECK_ALIAS(AOTMode); 372 373 if (FLAG_IS_DEFAULT(AOTCache) && FLAG_IS_DEFAULT(AOTConfiguration) && FLAG_IS_DEFAULT(AOTMode)) { 374 // AOTCache/AOTConfiguration/AOTMode not used. 375 return; 376 } else { 377 _new_aot_flags_used = true; 378 } 379 380 if (FLAG_IS_DEFAULT(AOTMode) || strcmp(AOTMode, "auto") == 0 || strcmp(AOTMode, "on") == 0) { 381 check_aotmode_auto_or_on(); 382 } else if (strcmp(AOTMode, "off") == 0) { 383 check_aotmode_off(); 384 } else { 385 // AOTMode is record or create 386 if (FLAG_IS_DEFAULT(AOTConfiguration)) { 387 vm_exit_during_initialization(err_msg("-XX:AOTMode=%s cannot be used without setting AOTConfiguration", AOTMode)); 388 } 389 390 if (strcmp(AOTMode, "record") == 0) { 391 check_aotmode_record(); 392 } else { 393 assert(strcmp(AOTMode, "create") == 0, "checked by AOTModeConstraintFunc"); 394 check_aotmode_create(); 395 } 396 } 397 } 398 399 void CDSConfig::check_aotmode_off() { 400 UseSharedSpaces = false; 401 RequireSharedSpaces = false; 402 } 403 404 void CDSConfig::check_aotmode_auto_or_on() { 405 if (!FLAG_IS_DEFAULT(AOTConfiguration)) { 406 vm_exit_during_initialization("AOTConfiguration can only be used with -XX:AOTMode=record or -XX:AOTMode=create"); 407 } 408 409 if (!FLAG_IS_DEFAULT(AOTCache)) { 410 assert(FLAG_IS_DEFAULT(SharedArchiveFile), "already checked"); 411 FLAG_SET_ERGO(SharedArchiveFile, AOTCache); 412 } 413 414 UseSharedSpaces = true; 415 if (FLAG_IS_DEFAULT(AOTMode) || (strcmp(AOTMode, "auto") == 0)) { 416 RequireSharedSpaces = false; 417 } else { 418 assert(strcmp(AOTMode, "on") == 0, "already checked"); 419 RequireSharedSpaces = true; 420 } 421 } 422 423 void CDSConfig::check_aotmode_record() { 424 if (!FLAG_IS_DEFAULT(AOTCache)) { 425 vm_exit_during_initialization("AOTCache must not be specified when using -XX:AOTMode=record"); 426 } 427 428 assert(FLAG_IS_DEFAULT(DumpLoadedClassList), "already checked"); 429 assert(FLAG_IS_DEFAULT(SharedArchiveFile), "already checked"); 430 FLAG_SET_ERGO(SharedArchiveFile, AOTConfiguration); 431 FLAG_SET_ERGO(DumpLoadedClassList, nullptr); 432 UseSharedSpaces = false; 433 RequireSharedSpaces = false; 434 _is_dumping_static_archive = true; 435 _is_dumping_preimage_static_archive = true; 436 437 // At VM exit, the module graph may be contaminated with program states. 438 // We will rebuild the module graph when dumping the CDS final image. 439 disable_heap_dumping(); 440 } 441 442 void CDSConfig::check_aotmode_create() { 443 if (FLAG_IS_DEFAULT(AOTCache)) { 444 vm_exit_during_initialization("AOTCache must be specified when using -XX:AOTMode=create"); 445 } 446 447 assert(FLAG_IS_DEFAULT(SharedArchiveFile), "already checked"); 448 449 _is_dumping_final_static_archive = true; 450 FLAG_SET_ERGO(SharedArchiveFile, AOTConfiguration); 451 UseSharedSpaces = true; 452 RequireSharedSpaces = true; 453 454 if (!FileMapInfo::is_preimage_static_archive(AOTConfiguration)) { 455 vm_exit_during_initialization("Must be a valid AOT configuration generated by the current JVM", AOTConfiguration); 456 } 457 458 CDSConfig::enable_dumping_static_archive(); 459 } 460 461 bool CDSConfig::check_vm_args_consistency(bool patch_mod_javabase, bool mode_flag_cmd_line) { 462 check_aot_flags(); 463 464 if (!FLAG_IS_DEFAULT(AOTMode)) { 465 // Using any form of the new AOTMode switch enables enhanced optimizations. 466 FLAG_SET_ERGO_IF_DEFAULT(AOTClassLinking, true); 467 } 468 469 if (AOTClassLinking) { 470 // If AOTClassLinking is specified, enable all AOT optimizations by default. 471 FLAG_SET_ERGO_IF_DEFAULT(AOTInvokeDynamicLinking, true); 472 } else { 473 // AOTInvokeDynamicLinking depends on AOTClassLinking. 474 FLAG_SET_ERGO(AOTInvokeDynamicLinking, false); 475 } 476 477 if (is_dumping_static_archive()) { 478 if (is_dumping_preimage_static_archive()) { 479 // Don't tweak execution mode 480 } else if (!mode_flag_cmd_line) { 481 // By default, -Xshare:dump runs in interpreter-only mode, which is required for deterministic archive. 482 // 483 // If your classlist is large and you don't care about deterministic dumping, you can use 484 // -Xshare:dump -Xmixed to improve dumping speed. 485 Arguments::set_mode_flags(Arguments::_int); 486 } else if (Arguments::mode() == Arguments::_comp) { 487 // -Xcomp may use excessive CPU for the test tiers. Also, -Xshare:dump runs a small and fixed set of 488 // Java code, so there's not much benefit in running -Xcomp. 489 log_info(cds)("reduced -Xcomp to -Xmixed for static dumping"); 490 Arguments::set_mode_flags(Arguments::_mixed); 491 } 492 493 // String deduplication may cause CDS to iterate the strings in different order from one 494 // run to another which resulting in non-determinstic CDS archives. 495 // Disable UseStringDeduplication while dumping CDS archive. 496 UseStringDeduplication = false; 497 498 // Don't use SoftReferences so that objects used by java.lang.invoke tables can be archived. 499 Arguments::PropertyList_add(new SystemProperty("java.lang.invoke.MethodHandleNatives.USE_SOFT_CACHE", "false", false)); 500 } 501 502 // RecordDynamicDumpInfo is not compatible with ArchiveClassesAtExit 503 if (ArchiveClassesAtExit != nullptr && RecordDynamicDumpInfo) { 504 jio_fprintf(defaultStream::output_stream(), 505 "-XX:+RecordDynamicDumpInfo cannot be used with -XX:ArchiveClassesAtExit.\n"); 506 return false; 507 } 508 509 if (ArchiveClassesAtExit == nullptr && !RecordDynamicDumpInfo) { 510 disable_dumping_dynamic_archive(); 511 } else { 512 enable_dumping_dynamic_archive(); 513 } 514 515 if (AutoCreateSharedArchive) { 516 if (SharedArchiveFile == nullptr) { 517 log_warning(cds)("-XX:+AutoCreateSharedArchive requires -XX:SharedArchiveFile"); 518 return false; 519 } 520 if (ArchiveClassesAtExit != nullptr) { 521 log_warning(cds)("-XX:+AutoCreateSharedArchive does not work with ArchiveClassesAtExit"); 522 return false; 523 } 524 } 525 526 if (is_using_archive() && patch_mod_javabase) { 527 Arguments::no_shared_spaces("CDS is disabled when " JAVA_BASE_NAME " module is patched."); 528 } 529 if (is_using_archive() && has_unsupported_runtime_module_options()) { 530 UseSharedSpaces = false; 531 } 532 533 if (is_dumping_archive()) { 534 // Always verify non-system classes during CDS dump 535 if (!BytecodeVerificationRemote) { 536 BytecodeVerificationRemote = true; 537 log_info(cds)("All non-system classes will be verified (-Xverify:remote) during CDS dump time."); 538 } 539 } 540 541 return true; 542 } 543 544 bool CDSConfig::is_dumping_classic_static_archive() { 545 return _is_dumping_static_archive && 546 !is_dumping_preimage_static_archive() && 547 !is_dumping_final_static_archive(); 548 } 549 550 bool CDSConfig::is_dumping_preimage_static_archive() { 551 return _is_dumping_preimage_static_archive; 552 } 553 554 bool CDSConfig::is_dumping_final_static_archive() { 555 return _is_dumping_final_static_archive; 556 } 557 558 bool CDSConfig::allow_only_single_java_thread() { 559 // See comments in JVM_StartThread() 560 return is_dumping_static_archive(); 561 } 562 563 bool CDSConfig::is_using_archive() { 564 return UseSharedSpaces; 565 } 566 567 bool CDSConfig::is_logging_lambda_form_invokers() { 568 return ClassListWriter::is_enabled() || is_dumping_dynamic_archive(); 569 } 570 571 void CDSConfig::stop_using_optimized_module_handling() { 572 _is_using_optimized_module_handling = false; 573 _is_dumping_full_module_graph = false; // This requires is_using_optimized_module_handling() 574 _is_using_full_module_graph = false; // This requires is_using_optimized_module_handling() 575 } 576 577 578 CDSConfig::DumperThreadMark::DumperThreadMark(JavaThread* current) { 579 assert(_dumper_thread == nullptr, "sanity"); 580 _dumper_thread = current; 581 } 582 583 CDSConfig::DumperThreadMark::~DumperThreadMark() { 584 assert(_dumper_thread != nullptr, "sanity"); 585 _dumper_thread = nullptr; 586 } 587 588 bool CDSConfig::current_thread_is_vm_or_dumper() { 589 Thread* t = Thread::current(); 590 return t != nullptr && (t->is_VM_thread() || t == _dumper_thread); 591 } 592 593 const char* CDSConfig::type_of_archive_being_loaded() { 594 if (is_dumping_final_static_archive()) { 595 return "AOT configuration file"; 596 } else if (new_aot_flags_used()) { 597 return "AOT cache"; 598 } else { 599 return "shared archive file"; 600 } 601 } 602 603 const char* CDSConfig::type_of_archive_being_written() { 604 if (is_dumping_preimage_static_archive()) { 605 return "AOT configuration file"; 606 } else if (new_aot_flags_used()) { 607 return "AOT cache"; 608 } else { 609 return "shared archive file"; 610 } 611 } 612 613 // If an incompatible VM options is found, return a text message that explains why 614 static const char* check_options_incompatible_with_dumping_heap() { 615 #if INCLUDE_CDS_JAVA_HEAP 616 if (!UseCompressedClassPointers) { 617 return "UseCompressedClassPointers must be true"; 618 } 619 620 // Almost all GCs support heap region dump, except ZGC (so far). 621 if (UseZGC) { 622 return "ZGC is not supported"; 623 } 624 625 return nullptr; 626 #else 627 return "JVM not configured for writing Java heap objects"; 628 #endif 629 } 630 631 void CDSConfig::log_reasons_for_not_dumping_heap() { 632 const char* reason; 633 634 assert(!is_dumping_heap(), "sanity"); 635 636 if (_disable_heap_dumping) { 637 reason = "Programmatically disabled"; 638 } else { 639 reason = check_options_incompatible_with_dumping_heap(); 640 } 641 642 assert(reason != nullptr, "sanity"); 643 log_info(cds)("Archived java heap is not supported: %s", reason); 644 } 645 646 #if INCLUDE_CDS_JAVA_HEAP 647 bool CDSConfig::are_vm_options_incompatible_with_dumping_heap() { 648 return check_options_incompatible_with_dumping_heap() != nullptr; 649 } 650 651 652 bool CDSConfig::is_dumping_heap() { 653 if (!(is_dumping_classic_static_archive() || is_dumping_final_static_archive()) 654 || are_vm_options_incompatible_with_dumping_heap() 655 || _disable_heap_dumping) { 656 return false; 657 } 658 return true; 659 } 660 661 bool CDSConfig::is_loading_heap() { 662 return ArchiveHeapLoader::is_in_use(); 663 } 664 665 bool CDSConfig::is_using_full_module_graph() { 666 if (ClassLoaderDataShared::is_full_module_graph_loaded()) { 667 return true; 668 } 669 670 if (!_is_using_full_module_graph) { 671 return false; 672 } 673 674 if (is_using_archive() && ArchiveHeapLoader::can_use()) { 675 // Classes used by the archived full module graph are loaded in JVMTI early phase. 676 assert(!(JvmtiExport::should_post_class_file_load_hook() && JvmtiExport::has_early_class_hook_env()), 677 "CDS should be disabled if early class hooks are enabled"); 678 return true; 679 } else { 680 _is_using_full_module_graph = false; 681 return false; 682 } 683 } 684 685 void CDSConfig::stop_dumping_full_module_graph(const char* reason) { 686 if (_is_dumping_full_module_graph) { 687 _is_dumping_full_module_graph = false; 688 if (reason != nullptr) { 689 log_info(cds)("full module graph cannot be dumped: %s", reason); 690 } 691 } 692 } 693 694 void CDSConfig::stop_using_full_module_graph(const char* reason) { 695 assert(!ClassLoaderDataShared::is_full_module_graph_loaded(), "you call this function too late!"); 696 if (_is_using_full_module_graph) { 697 _is_using_full_module_graph = false; 698 if (reason != nullptr) { 699 log_info(cds)("full module graph cannot be loaded: %s", reason); 700 } 701 } 702 } 703 704 bool CDSConfig::is_dumping_aot_linked_classes() { 705 if (is_dumping_preimage_static_archive()) { 706 return false; 707 } else if (is_dumping_dynamic_archive()) { 708 return is_using_full_module_graph() && AOTClassLinking; 709 } else if (is_dumping_static_archive()) { 710 return is_dumping_full_module_graph() && AOTClassLinking; 711 } else { 712 return false; 713 } 714 } 715 716 bool CDSConfig::is_using_aot_linked_classes() { 717 // Make sure we have the exact same module graph as in the assembly phase, or else 718 // some aot-linked classes may not be visible so cannot be loaded. 719 return is_using_full_module_graph() && _has_aot_linked_classes; 720 } 721 722 void CDSConfig::set_has_aot_linked_classes(bool has_aot_linked_classes) { 723 _has_aot_linked_classes |= has_aot_linked_classes; 724 } 725 726 bool CDSConfig::is_initing_classes_at_dump_time() { 727 return is_dumping_heap() && is_dumping_aot_linked_classes(); 728 } 729 730 bool CDSConfig::is_dumping_invokedynamic() { 731 // Requires is_dumping_aot_linked_classes(). Otherwise the classes of some archived heap 732 // objects used by the archive indy callsites may be replaced at runtime. 733 return AOTInvokeDynamicLinking && is_dumping_aot_linked_classes() && is_dumping_heap(); 734 } 735 736 bool CDSConfig::is_loading_invokedynamic() { 737 return UseSharedSpaces && is_using_full_module_graph() && _has_archived_invokedynamic; 738 } 739 740 #endif // INCLUDE_CDS_JAVA_HEAP