< prev index next >

src/hotspot/share/cds/cdsConfig.cpp

Print this page
*** 22,17 ***
--- 22,22 ---
   *
   */
  
  #include "cds/archiveHeapLoader.hpp"
  #include "cds/cdsConfig.hpp"
+ #include "cds/cds_globals.hpp"
  #include "cds/classListWriter.hpp"
  #include "cds/filemap.hpp"
  #include "cds/heapShared.hpp"
+ #include "cds/metaspaceShared.hpp"
  #include "classfile/classLoaderDataShared.hpp"
  #include "classfile/moduleEntry.hpp"
+ #include "classfile/systemDictionaryShared.hpp"
+ #include "code/SCCache.hpp"
  #include "include/jvm_io.h"
  #include "logging/log.hpp"
+ #include "prims/jvmtiExport.hpp"
  #include "memory/universe.hpp"
  #include "runtime/arguments.hpp"
  #include "runtime/globals_extension.hpp"
  #include "runtime/java.hpp"
  #include "runtime/vmThread.hpp"

*** 46,10 ***
--- 51,13 ---
  bool CDSConfig::_is_using_optimized_module_handling = true;
  bool CDSConfig::_is_dumping_full_module_graph = true;
  bool CDSConfig::_is_using_full_module_graph = true;
  bool CDSConfig::_has_aot_linked_classes = false;
  bool CDSConfig::_has_archived_invokedynamic = false;
+ bool CDSConfig::_is_loading_packages = false;
+ bool CDSConfig::_is_loading_protection_domains = false;
+ bool CDSConfig::_is_security_manager_allowed = false;
  bool CDSConfig::_old_cds_flags_used = false;
  bool CDSConfig::_new_aot_flags_used = false;
  bool CDSConfig::_disable_heap_dumping = false;
  
  char* CDSConfig::_default_archive_path = nullptr;

*** 61,17 ***
  int CDSConfig::get_status() {
    assert(Universe::is_fully_initialized(), "status is finalized only after Universe is initialized");
    return (is_dumping_archive()              ? IS_DUMPING_ARCHIVE : 0) |
           (is_dumping_static_archive()       ? IS_DUMPING_STATIC_ARCHIVE : 0) |
           (is_logging_lambda_form_invokers() ? IS_LOGGING_LAMBDA_FORM_INVOKERS : 0) |
!          (is_using_archive()                ? IS_USING_ARCHIVE : 0);
  }
  
  void CDSConfig::initialize() {
    if (is_dumping_static_archive() && !is_dumping_final_static_archive()) {
      if (RequireSharedSpaces) {
!       warning("Cannot dump shared archive while using shared archive");
      }
      UseSharedSpaces = false;
    }
  
    // Initialize shared archive paths which could include both base and dynamic archive paths
--- 69,32 ---
  int CDSConfig::get_status() {
    assert(Universe::is_fully_initialized(), "status is finalized only after Universe is initialized");
    return (is_dumping_archive()              ? IS_DUMPING_ARCHIVE : 0) |
           (is_dumping_static_archive()       ? IS_DUMPING_STATIC_ARCHIVE : 0) |
           (is_logging_lambda_form_invokers() ? IS_LOGGING_LAMBDA_FORM_INVOKERS : 0) |
!          (is_using_archive()                ? IS_USING_ARCHIVE : 0) |
+          (is_dumping_heap()                 ? IS_DUMPING_HEAP : 0) |
+          (is_logging_dynamic_proxies()      ? IS_LOGGING_DYNAMIC_PROXIES : 0) |
+          (is_dumping_packages()             ? IS_DUMPING_PACKAGES : 0) |
+          (is_dumping_protection_domains()   ? IS_DUMPING_PROTECTION_DOMAINS : 0);
  }
  
  void CDSConfig::initialize() {
    if (is_dumping_static_archive() && !is_dumping_final_static_archive()) {
+     // If dumping the classic archive, or making an AOT training run (dumping a preimage archive),
+     // for sanity, parse all classes from classfiles.
+     // TODO: in the future, if we want to support re-training on top of an existing AOT cache, this
+     // needs to be changed.
      if (RequireSharedSpaces) {
!       if (is_experimental_leyden_workflow()) {
+         log_info(cds)("-Xshare:on flag is ignored when creating a CacheDataStore");
+       } else {
+         // -Xshare and -XX:AOTMode flags are mutually exclusive:
+         //   Class workflow: -Xshare:on and -Xshare:dump cannot take effect at the same time.
+         //   JEP 483 workflow: -XX:AOTMode:record and -XX:AOTMode=on cannot take effect at the same time.
+         ShouldNotReachHere();
+       }
      }
      UseSharedSpaces = false;
    }
  
    // Initialize shared archive paths which could include both base and dynamic archive paths

*** 175,10 ***
--- 198,14 ---
      if (is_dumping_archive() && archives > 1) {
        vm_exit_during_initialization(
          "Cannot have more than 1 archive file specified in -XX:SharedArchiveFile during CDS dumping");
      }
  
+     if (CDSPreimage != nullptr && archives > 1) {
+       vm_exit_during_initialization("CDSPreimage must point to a single file", CDSPreimage);
+     }
+ 
      if (is_dumping_static_archive()) {
        assert(archives == 1, "must be");
        // Static dump is simple: only one archive is allowed in SharedArchiveFile. This file
        // will be overwritten no matter regardless of its contents
        _static_archive_path = os::strdup_check_oom(SharedArchiveFile, mtArguments);

*** 199,10 ***
--- 226,14 ---
        if (archives == 1) {
          char* base_archive_path = nullptr;
          bool success =
            FileMapInfo::get_base_archive_name_from_header(SharedArchiveFile, &base_archive_path);
          if (!success) {
+           if (CDSPreimage != nullptr) {
+             vm_exit_during_initialization("Unable to map shared spaces from CDSPreimage", CDSPreimage);
+           }
+ 
            // If +AutoCreateSharedArchive and the specified shared archive does not exist,
            // regenerate the dynamic archive base on default archive.
            if (AutoCreateSharedArchive && !os::file_exists(SharedArchiveFile)) {
              enable_dumping_dynamic_archive();
              ArchiveClassesAtExit = const_cast<char *>(SharedArchiveFile);

*** 252,14 ***
        }
      }
    }
  }
  
  void CDSConfig::check_internal_module_property(const char* key, const char* value) {
    if (Arguments::is_incompatible_cds_internal_module_property(key)) {
      stop_using_optimized_module_handling();
!     log_info(cds)("optimized module handling: disabled due to incompatible property: %s=%s", key, value);
    }
  }
  
  void CDSConfig::check_incompatible_property(const char* key, const char* value) {
    static const char* incompatible_properties[] = {
--- 283,26 ---
        }
      }
    }
  }
  
+ static char* bad_module_prop_key   = nullptr;
+ static char* bad_module_prop_value = nullptr;
+ 
  void CDSConfig::check_internal_module_property(const char* key, const char* value) {
    if (Arguments::is_incompatible_cds_internal_module_property(key)) {
      stop_using_optimized_module_handling();
!     if (bad_module_prop_key == nullptr) {
+       // We don't want to print an unconditional warning here, as we are still processing the command line.
+       // A later argument may specify something like -Xshare:off, which makes such a warning irrelevant.
+       //
+       // Instead, we save the info so we can warn when necessary: we are doing it only during CacheDataStore
+       // creation for now, but could add it to other places.
+       bad_module_prop_key   = os::strdup(key);
+       bad_module_prop_value = os::strdup(value);
+     }
+     log_info(cds)("optimized module handling/full module graph: disabled due to incompatible property: %s=%s", key, value);
    }
  }
  
  void CDSConfig::check_incompatible_property(const char* key, const char* value) {
    static const char* incompatible_properties[] = {

*** 275,10 ***
--- 318,16 ---
        log_info(cds)("full module graph: disabled due to incompatible property: %s=%s", key, value);
        break;
      }
    }
  
+   // Match the logic in java/lang/System.java, but we need to know this before the System class is initialized.
+   if (strcmp(key, "java.security.manager") == 0) {
+     if (strcmp(value, "disallowed") != 0) {
+       _is_security_manager_allowed = true;
+     }
+   }
  }
  
  // Returns any JVM command-line option, such as "--patch-module", that's not supported by CDS.
  static const char* find_any_unsupported_module_option() {
    // Note that arguments.cpp has translated the command-line options into properties. If we find an

*** 456,28 ***
    }
  
    CDSConfig::enable_dumping_static_archive();
  }
  
! bool CDSConfig::check_vm_args_consistency(bool patch_mod_javabase, bool mode_flag_cmd_line) {
    check_aot_flags();
  
    if (!FLAG_IS_DEFAULT(AOTMode)) {
      // Using any form of the new AOTMode switch enables enhanced optimizations.
      FLAG_SET_ERGO_IF_DEFAULT(AOTClassLinking, true);
    }
  
    if (AOTClassLinking) {
!     // If AOTClassLinking is specified, enable all AOT optimizations by default.
      FLAG_SET_ERGO_IF_DEFAULT(AOTInvokeDynamicLinking, true);
    } else {
!     // AOTInvokeDynamicLinking depends on AOTClassLinking.
      FLAG_SET_ERGO(AOTInvokeDynamicLinking, false);
    }
  
    if (is_dumping_static_archive()) {
!     if (is_dumping_preimage_static_archive()) {
        // Don't tweak execution mode
      } else if (!mode_flag_cmd_line) {
        // By default, -Xshare:dump runs in interpreter-only mode, which is required for deterministic archive.
        //
        // If your classlist is large and you don't care about deterministic dumping, you can use
--- 505,67 ---
    }
  
    CDSConfig::enable_dumping_static_archive();
  }
  
! bool CDSConfig::check_vm_args_consistency(bool patch_mod_javabase, bool mode_flag_cmd_line, bool xshare_auto_cmd_line) {
    check_aot_flags();
  
    if (!FLAG_IS_DEFAULT(AOTMode)) {
      // Using any form of the new AOTMode switch enables enhanced optimizations.
      FLAG_SET_ERGO_IF_DEFAULT(AOTClassLinking, true);
    }
  
+   if (CacheDataStore != nullptr) {
+     if (!setup_experimental_leyden_workflow(xshare_auto_cmd_line)) {
+       return false;
+     }
+   } else {
+     if (CDSPreimage != nullptr) {
+       vm_exit_during_initialization("CDSPreimage must be specified only when CacheDataStore is specified");
+     }
+ 
+     setup_compiler_args();
+   }
+ 
    if (AOTClassLinking) {
!     // If AOTClassLinking is specified, enable all these optimizations by default.
      FLAG_SET_ERGO_IF_DEFAULT(AOTInvokeDynamicLinking, true);
+     FLAG_SET_ERGO_IF_DEFAULT(ArchiveDynamicProxies, true);
+     FLAG_SET_ERGO_IF_DEFAULT(ArchiveLoaderLookupCache, true);
+     FLAG_SET_ERGO_IF_DEFAULT(ArchivePackages, true);
+     FLAG_SET_ERGO_IF_DEFAULT(ArchiveProtectionDomains, true);
+     FLAG_SET_ERGO_IF_DEFAULT(ArchiveReflectionData, true);
    } else {
!     // All of these *might* depend on AOTClassLinking. Better be safe than sorry.
      FLAG_SET_ERGO(AOTInvokeDynamicLinking, false);
+     FLAG_SET_ERGO(ArchiveDynamicProxies, false);
+     FLAG_SET_ERGO(ArchiveLoaderLookupCache, false);
+     FLAG_SET_ERGO(ArchivePackages, false);
+     FLAG_SET_ERGO(ArchiveProtectionDomains, false);
+     FLAG_SET_ERGO(ArchiveReflectionData, false);
+ 
+     if (CDSConfig::is_dumping_archive()) {
+       FLAG_SET_ERGO(RecordTraining, false);
+       FLAG_SET_ERGO(ReplayTraining, false);
+       FLAG_SET_ERGO(StoreCachedCode, false);
+       FLAG_SET_ERGO(LoadCachedCode, false);
+     }
    }
  
+   if (StoreCachedCode) {
+     log_info(cds)("ArchiveAdapters is enabled");
+     FLAG_SET_ERGO_IF_DEFAULT(ArchiveAdapters, true);
+   }
+ 
+ #ifdef _WINDOWS
+   // This optimization is not working on Windows for some reason. See JDK-8338604.
+   FLAG_SET_ERGO(ArchiveReflectionData, false);
+ #endif
+ 
    if (is_dumping_static_archive()) {
!     if (is_dumping_preimage_static_archive() || is_dumping_final_static_archive()) {
        // Don't tweak execution mode
      } else if (!mode_flag_cmd_line) {
        // By default, -Xshare:dump runs in interpreter-only mode, which is required for deterministic archive.
        //
        // If your classlist is large and you don't care about deterministic dumping, you can use

*** 492,13 ***
  
      // String deduplication may cause CDS to iterate the strings in different order from one
      // run to another which resulting in non-determinstic CDS archives.
      // Disable UseStringDeduplication while dumping CDS archive.
      UseStringDeduplication = false;
- 
-     // Don't use SoftReferences so that objects used by java.lang.invoke tables can be archived.
-     Arguments::PropertyList_add(new SystemProperty("java.lang.invoke.MethodHandleNatives.USE_SOFT_CACHE", "false", false));
    }
  
    // RecordDynamicDumpInfo is not compatible with ArchiveClassesAtExit
    if (ArchiveClassesAtExit != nullptr && RecordDynamicDumpInfo) {
      jio_fprintf(defaultStream::output_stream(),
--- 580,10 ---

*** 536,10 ***
--- 621,149 ---
        BytecodeVerificationRemote = true;
        log_info(cds)("All non-system classes will be verified (-Xverify:remote) during CDS dump time.");
      }
    }
  
+   if (AOTClassLinking) {
+     if (is_dumping_final_static_archive() && !is_dumping_full_module_graph()) {
+       if (bad_module_prop_key != nullptr) {
+         log_warning(cds)("optimized module handling/full module graph: disabled due to incompatible property: %s=%s",
+                          bad_module_prop_key, bad_module_prop_value);
+       }
+       if (is_experimental_leyden_workflow()) {
+         vm_exit_during_initialization("CacheDataStore cannot be created because AOTClassLinking is enabled but full module graph is disabled");
+       } else {
+         vm_exit_during_initialization("AOT cache cannot be created because AOTClassLinking is enabled but full module graph is disabled");
+       }
+     }
+   }
+ 
+   return true;
+ }
+ 
+ void CDSConfig::setup_compiler_args() {
+   // AOT profiles and AOT-compiled methods are supported only in the JEP 483 workflow.
+   bool can_dump_profile_and_compiled_code = AOTClassLinking && new_aot_flags_used();
+ 
+   if (is_dumping_preimage_static_archive() && can_dump_profile_and_compiled_code) {
+     // JEP 483 workflow -- training
+     FLAG_SET_ERGO_IF_DEFAULT(RecordTraining, true);
+     FLAG_SET_ERGO(ReplayTraining, false);
+     FLAG_SET_ERGO(StoreCachedCode, false);
+     FLAG_SET_ERGO(LoadCachedCode, false);
+   } else if (is_dumping_final_static_archive() && can_dump_profile_and_compiled_code) {
+     // JEP 483 workflow -- assembly
+     FLAG_SET_ERGO(RecordTraining, false); // This will be updated inside MetaspaceShared::preload_and_dump()
+     FLAG_SET_ERGO_IF_DEFAULT(ReplayTraining, true);
+     FLAG_SET_ERGO_IF_DEFAULT(StoreCachedCode, true);
+     FLAG_SET_ERGO(LoadCachedCode, false);
+     disable_dumping_cached_code(); // Cannot dump cached code until metadata and heap are dumped.
+   } else if (is_using_archive() && new_aot_flags_used()) {
+     // JEP 483 workflow -- production
+     FLAG_SET_ERGO(RecordTraining, false);
+     FLAG_SET_ERGO_IF_DEFAULT(ReplayTraining, true);
+     FLAG_SET_ERGO(StoreCachedCode, false);
+     FLAG_SET_ERGO_IF_DEFAULT(LoadCachedCode, true);
+ 
+     if (UseSharedSpaces && FLAG_IS_DEFAULT(AOTMode)) {
+       log_info(cds)("Enabled -XX:AOTMode=on by default for troubleshooting Leyden prototype");
+       RequireSharedSpaces = true;
+     }
+   } else {
+     FLAG_SET_ERGO(ReplayTraining, false);
+     FLAG_SET_ERGO(RecordTraining, false);
+     FLAG_SET_ERGO(StoreCachedCode, false);
+     FLAG_SET_ERGO(LoadCachedCode, false);
+   }
+ }
+ 
+ // Ergo set-up of various flags used by the experimental workflow that uses -XX:CacheDataStore. This workflow
+ // is deprecated and will be removed from Leyden.
+ bool CDSConfig::setup_experimental_leyden_workflow(bool xshare_auto_cmd_line) {
+   // Leyden temp work-around:
+   //
+   // By default, when using CacheDataStore, use the HeapBasedNarrowOop mode so that
+   // AOT code can be always work regardless of runtime heap range.
+   //
+   // If you are *absolutely sure* that the CompressedOops::mode() will be the same
+   // between training and production runs (e.g., if you specify -Xmx128m
+   // for both training and production runs, and you know the OS will always reserve
+   // the heap under 4GB), you can explicitly disable this with:
+   //     java -XX:-UseCompatibleCompressedOops -XX:CacheDataStore=...
+   // However, this is risky and there's a chance that the production run will be slower
+   // because it is unable to load the AOT code cache.
+ #ifdef _LP64
+   // FLAG_SET_ERGO_IF_DEFAULT(UseCompatibleCompressedOops, true); // FIXME @iklam - merge with mainline - UseCompatibleCompressedOops
+ #endif
+ 
+   if (FLAG_IS_DEFAULT(AOTClassLinking)) {
+     FLAG_SET_ERGO(AOTClassLinking, true);
+   }
+ 
+   if (SharedArchiveFile != nullptr) {
+     vm_exit_during_initialization("CacheDataStore and SharedArchiveFile cannot be both specified");
+   }
+   if (!AOTClassLinking) {
+     vm_exit_during_initialization("CacheDataStore requires AOTClassLinking");
+   }
+ 
+   if (CDSPreimage == nullptr) {
+     if (os::file_exists(CacheDataStore) /* && TODO: Need to check if CDS file is valid*/) {
+       // The CacheDataStore is already up to date. Use it. Also turn on cached code by default.
+       SharedArchiveFile = CacheDataStore;
+       FLAG_SET_ERGO_IF_DEFAULT(ReplayTraining, true);
+       FLAG_SET_ERGO_IF_DEFAULT(LoadCachedCode, true);
+ 
+       // Leyden temp: make sure the user knows if CDS archive somehow fails to load.
+       if (UseSharedSpaces && !xshare_auto_cmd_line) {
+         log_info(cds)("Enabled -Xshare:on by default for troubleshooting Leyden prototype");
+         RequireSharedSpaces = true;
+       }
+     } else {
+       // The preimage dumping phase -- run the app and write the preimage file
+       size_t len = strlen(CacheDataStore) + 10;
+       char* preimage = AllocateHeap(len, mtArguments);
+       jio_snprintf(preimage, len, "%s.preimage", CacheDataStore);
+ 
+       UseSharedSpaces = false;
+       enable_dumping_static_archive();
+       SharedArchiveFile = preimage;
+       log_info(cds)("CacheDataStore needs to be updated. Writing %s file", SharedArchiveFile);
+ 
+       // At VM exit, the module graph may be contaminated with program states. We should rebuild the
+       // module graph when dumping the CDS final image.
+       log_info(cds)("full module graph: disabled when writing CDS preimage");
+       disable_heap_dumping();
+       stop_dumping_full_module_graph();
+       FLAG_SET_ERGO(ArchivePackages, false);
+       FLAG_SET_ERGO(ArchiveProtectionDomains, false);
+       FLAG_SET_ERGO_IF_DEFAULT(RecordTraining, true);
+       _is_dumping_static_archive = true;
+       _is_dumping_preimage_static_archive = true;
+     }
+   } else {
+     // The final image dumping phase -- load the preimage and write the final image file
+     SharedArchiveFile = CDSPreimage;
+     UseSharedSpaces = true;
+     log_info(cds)("Generate CacheDataStore %s from CDSPreimage %s", CacheDataStore, CDSPreimage);
+     // Force -Xbatch for AOT compilation.
+     if (FLAG_SET_CMDLINE(BackgroundCompilation, false) != JVMFlag::SUCCESS) {
+       return false;
+     }
+     RecordTraining = false; // This will be updated inside MetaspaceShared::preload_and_dump()
+ 
+     FLAG_SET_ERGO_IF_DEFAULT(ReplayTraining, true);
+     // Settings for AOT
+     FLAG_SET_ERGO_IF_DEFAULT(StoreCachedCode, true);
+     if (StoreCachedCode) {
+       // Cannot dump cached code until metadata and heap are dumped.
+       disable_dumping_cached_code();
+     }
+     _is_dumping_static_archive = true;
+     _is_dumping_final_static_archive = true;
+   }
+ 
    return true;
  }
  
  bool CDSConfig::is_dumping_classic_static_archive() {
    return _is_dumping_static_archive &&

*** 549,25 ***
  
  bool CDSConfig::is_dumping_preimage_static_archive() {
    return _is_dumping_preimage_static_archive;
  }
  
  bool CDSConfig::is_dumping_final_static_archive() {
    return _is_dumping_final_static_archive;
  }
  
  bool CDSConfig::allow_only_single_java_thread() {
    // See comments in JVM_StartThread()
!   return is_dumping_static_archive();
  }
  
  bool CDSConfig::is_using_archive() {
    return UseSharedSpaces;
  }
  
  bool CDSConfig::is_logging_lambda_form_invokers() {
!   return ClassListWriter::is_enabled() || is_dumping_dynamic_archive();
  }
  
  void CDSConfig::stop_using_optimized_module_handling() {
    _is_using_optimized_module_handling = false;
    _is_dumping_full_module_graph = false; // This requires is_using_optimized_module_handling()
--- 773,61 ---
  
  bool CDSConfig::is_dumping_preimage_static_archive() {
    return _is_dumping_preimage_static_archive;
  }
  
+ bool CDSConfig::is_dumping_preimage_static_archive_with_triggers() {
+   return (!FLAG_IS_DEFAULT(AOTEndTrainingOnMethodEntry)) && is_dumping_preimage_static_archive();
+ }
+ 
  bool CDSConfig::is_dumping_final_static_archive() {
    return _is_dumping_final_static_archive;
  }
  
  bool CDSConfig::allow_only_single_java_thread() {
    // See comments in JVM_StartThread()
!   return is_dumping_classic_static_archive() || is_dumping_final_static_archive();
+ }
+ 
+ bool CDSConfig::is_dumping_regenerated_lambdaform_invokers() {
+   if (is_dumping_final_static_archive()) {
+     // No need to regenerate -- the lambda form invokers should have been regenerated
+     // in the preimage archive (if allowed)
+     return false;
+   } else if (is_dumping_dynamic_archive() && is_using_aot_linked_classes()) {
+     // The base archive has aot-linked classes that may have AOT-resolved CP references
+     // that point to the lambda form invokers in the base archive. Such pointers will
+     // be invalid if lambda form invokers are regenerated in the dynamic archive.
+     return false;
+   } else if (CDSConfig::is_dumping_invokedynamic()) {
+     // Work around JDK-8310831, as some methods in lambda form holder classes may not get generated.
+     return false;
+   } else {
+     return is_dumping_archive();
+   }
+ }
+ 
+ bool CDSConfig::is_logging_dynamic_proxies() {
+   return ClassListWriter::is_enabled() || is_dumping_preimage_static_archive();
+ }
+ 
+ // Preserve all states that were examined used during dumptime verification, such
+ // that the verification result (pass or fail) cannot be changed at runtime.
+ //
+ // For example, if the verification of ik requires that class A must be a subtype of B,
+ // then this relationship between A and B cannot be changed at runtime. I.e., the app
+ // cannot load alternative versions of A and B such that A is not a subtype of B.
+ bool CDSConfig::preserve_all_dumptime_verification_states(const InstanceKlass* ik) {
+   return is_dumping_aot_linked_classes() && SystemDictionaryShared::is_builtin(ik);
  }
  
  bool CDSConfig::is_using_archive() {
    return UseSharedSpaces;
  }
  
  bool CDSConfig::is_logging_lambda_form_invokers() {
!   return ClassListWriter::is_enabled() || is_dumping_dynamic_archive() || is_dumping_preimage_static_archive();
  }
  
  void CDSConfig::stop_using_optimized_module_handling() {
    _is_using_optimized_module_handling = false;
    _is_dumping_full_module_graph = false; // This requires is_using_optimized_module_handling()

*** 712,15 ***
--- 972,24 ---
      return false;
    }
  }
  
  bool CDSConfig::is_using_aot_linked_classes() {
+   if (is_dumping_final_static_archive()) {
+     // We assume that the final image is being dumped with the exact same module graph as the training run,
+     // so all aot-linked classes can be loaded.
+     return _has_aot_linked_classes;
+   }
    // Make sure we have the exact same module graph as in the assembly phase, or else
    // some aot-linked classes may not be visible so cannot be loaded.
    return is_using_full_module_graph() && _has_aot_linked_classes;
  }
  
+ bool CDSConfig::is_dumping_dynamic_proxies() {
+   return is_dumping_full_module_graph() && is_dumping_invokedynamic() && ArchiveDynamicProxies;
+ }
+ 
  void CDSConfig::set_has_aot_linked_classes(bool has_aot_linked_classes) {
    _has_aot_linked_classes |= has_aot_linked_classes;
  }
  
  bool CDSConfig::is_initing_classes_at_dump_time() {

*** 731,10 ***
--- 1000,65 ---
    // Requires is_dumping_aot_linked_classes(). Otherwise the classes of some archived heap
    // objects used by the archive indy callsites may be replaced at runtime.
    return AOTInvokeDynamicLinking && is_dumping_aot_linked_classes() && is_dumping_heap();
  }
  
+ bool CDSConfig::is_dumping_packages() {
+   return ArchivePackages && is_dumping_heap();
+ }
+ 
+ bool CDSConfig::is_loading_packages() {
+   return UseSharedSpaces && is_using_full_module_graph() && _is_loading_packages;
+ }
+ 
+ bool CDSConfig::is_dumping_protection_domains() {
+   if (_is_security_manager_allowed) {
+     // For sanity, don't archive PDs. TODO: can this be relaxed?
+     return false;
+   }
+   // Archived PDs for the modules will reference their java.lang.Module, which must
+   // also be archived.
+   return ArchiveProtectionDomains && is_dumping_full_module_graph();
+ }
+ 
+ bool CDSConfig::is_loading_protection_domains() {
+   if (_is_security_manager_allowed) {
+     // For sanity, don't used any archived PDs. TODO: can this be relaxed?
+     return false;
+   }
+   return UseSharedSpaces && is_using_full_module_graph() && _is_loading_protection_domains;
+ }
+ 
+ bool CDSConfig::is_dumping_reflection_data() {
+   // reflection data use LambdaForm classes
+   return ArchiveReflectionData && is_dumping_invokedynamic();
+ }
+ 
  bool CDSConfig::is_loading_invokedynamic() {
    return UseSharedSpaces && is_using_full_module_graph() && _has_archived_invokedynamic;
  }
  
  #endif // INCLUDE_CDS_JAVA_HEAP
+ 
+ // This is allowed by default. We disable it only in the final image dump before the
+ // metadata and heap are dumped.
+ static bool _is_dumping_cached_code = true;
+ 
+ bool CDSConfig::is_dumping_cached_code() {
+   return _is_dumping_cached_code;
+ }
+ 
+ void CDSConfig::disable_dumping_cached_code() {
+   _is_dumping_cached_code = false;
+ }
+ 
+ void CDSConfig::enable_dumping_cached_code() {
+   _is_dumping_cached_code = true;
+ }
+ 
+ bool CDSConfig::is_dumping_adapters() {
+   return (ArchiveAdapters && is_dumping_final_static_archive());
+ }
+ 
+ bool CDSConfig::is_experimental_leyden_workflow() {
+   return CacheDataStore != nullptr || CDSPreimage != nullptr;
+ }
< prev index next >