< prev index next >

src/hotspot/share/cds/cdsConfig.cpp

Print this page
*** 22,22 ***
--- 22,27 ---
   *
   */
  
  #include "cds/aotLogging.hpp"
  #include "cds/aotMapLogger.hpp"
+ #include "cds/aotMetaspace.hpp"
  #include "cds/archiveHeapLoader.hpp"
+ #include "cds/cds_globals.hpp"
  #include "cds/cdsConfig.hpp"
  #include "cds/classListWriter.hpp"
  #include "cds/filemap.hpp"
  #include "cds/heapShared.hpp"
  #include "classfile/classLoaderDataShared.hpp"
  #include "classfile/moduleEntry.hpp"
+ #include "classfile/systemDictionaryShared.hpp"
  #include "code/aotCodeCache.hpp"
+ #include "compiler/compilerDefinitions.inline.hpp"
  #include "include/jvm_io.h"
  #include "logging/log.hpp"
  #include "memory/universe.hpp"
  #include "prims/jvmtiAgentList.hpp"
+ #include "prims/jvmtiExport.hpp"
  #include "runtime/arguments.hpp"
  #include "runtime/globals_extension.hpp"
  #include "runtime/java.hpp"
  #include "runtime/vmThread.hpp"
  #include "utilities/defaultStream.hpp"

*** 70,11 ***
    return (is_dumping_aot_linked_classes()   ? IS_DUMPING_AOT_LINKED_CLASSES : 0) |
           (is_dumping_archive()              ? IS_DUMPING_ARCHIVE : 0) |
           (is_dumping_method_handles()       ? IS_DUMPING_METHOD_HANDLES : 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);
  }
  
  DEBUG_ONLY(static bool _cds_ergo_initialize_started = false);
  
  void CDSConfig::ergo_initialize() {
--- 75,13 ---
    return (is_dumping_aot_linked_classes()   ? IS_DUMPING_AOT_LINKED_CLASSES : 0) |
           (is_dumping_archive()              ? IS_DUMPING_ARCHIVE : 0) |
           (is_dumping_method_handles()       ? IS_DUMPING_METHOD_HANDLES : 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);
  }
  
  DEBUG_ONLY(static bool _cds_ergo_initialize_started = false);
  
  void CDSConfig::ergo_initialize() {

*** 107,10 ***
--- 114,30 ---
    if (!is_dumping_heap()) {
      _is_dumping_full_module_graph = false;
    }
  
    AOTMapLogger::ergo_initialize();
+ 
+ #ifdef _LP64
+   //
+   // By default, when using AOTClassLinking, use the CompressedOops::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:+UnlockDiagnosticVMOptions -XX:-UseCompatibleCompressedOops ...
+   // However, this is risky and there's a chance that the production run will be slower
+   // than expected because it is unable to load the AOT code cache.
+   //
+   if (UseCompressedOops && AOTCodeCache::is_caching_enabled()) {
+     FLAG_SET_ERGO_IF_DEFAULT(UseCompatibleCompressedOops, true);
+   } else if (!FLAG_IS_DEFAULT(UseCompatibleCompressedOops)) {
+     FLAG_SET_ERGO(UseCompatibleCompressedOops, false);
+   }
+ #endif // _LP64
  }
  
  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.

*** 296,13 ***
--- 323,25 ---
        }
      }
    }
  }
  
+ 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 AOT Cache
+       // creation for now, but could add it to other places.
+       bad_module_prop_key   = os::strdup(key);
+       bad_module_prop_value = os::strdup(value);
+     }
      aot_log_info(aot)("optimized module handling: disabled due to incompatible property: %s=%s", key, value);
    }
  }
  
  void CDSConfig::check_incompatible_property(const char* key, const char* value) {

*** 318,11 ***
        stop_using_full_module_graph();
        aot_log_info(aot)("full module graph: disabled due to incompatible property: %s=%s", key, value);
        break;
      }
    }
- 
  }
  
  // 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
--- 357,10 ---

*** 634,17 ***
    }
  
    setup_compiler_args();
  
    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 during AOT training run
      } else if (is_dumping_final_static_archive()) {
        if (Arguments::mode() == Arguments::_comp) {
--- 672,37 ---
    }
  
    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(ArchiveReflectionData, true);
+ 
+     // For simplicity, enable these by default only for new workflow
+     if (new_aot_flags_used()) {
+       // These flags will be removed when JDK-8350550 is merged from mainline
+       FLAG_SET_ERGO_IF_DEFAULT(ArchivePackages, true);
+       FLAG_SET_ERGO_IF_DEFAULT(ArchiveProtectionDomains, 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(AOTRecordTraining, false);
+       FLAG_SET_ERGO(AOTReplayTraining, false);
+       AOTCodeCache::disable_caching();
+     }
    }
    if (is_dumping_static_archive()) {
      if (is_dumping_preimage_static_archive()) {
        // Don't tweak execution mode during AOT training run
      } else if (is_dumping_final_static_archive()) {
        if (Arguments::mode() == Arguments::_comp) {

*** 711,37 ***
        BytecodeVerificationRemote = true;
        aot_log_info(aot)("All non-system classes will be verified (-Xverify:remote) during CDS dump time.");
      }
    }
  
    return true;
  }
  
  void CDSConfig::setup_compiler_args() {
!   // AOT profiles and AOT-compiled code 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(AOTRecordTraining, true);
      FLAG_SET_ERGO(AOTReplayTraining, false);
      AOTCodeCache::disable_caching(); // No AOT code generation during training run
    } else if (is_dumping_final_static_archive() && can_dump_profile_and_compiled_code) {
      // JEP 483 workflow -- assembly
      FLAG_SET_ERGO(AOTRecordTraining, false);
      FLAG_SET_ERGO_IF_DEFAULT(AOTReplayTraining, true);
      AOTCodeCache::enable_caching(); // Generate AOT code during assembly phase.
      disable_dumping_aot_code();     // Don't dump AOT code until metadata and heap are dumped.
!   } else if (is_using_archive() && new_aot_flags_used()) {
      // JEP 483 workflow -- production
      FLAG_SET_ERGO(AOTRecordTraining, false);
      FLAG_SET_ERGO_IF_DEFAULT(AOTReplayTraining, true);
      AOTCodeCache::enable_caching();
    } else {
      FLAG_SET_ERGO(AOTReplayTraining, false);
      FLAG_SET_ERGO(AOTRecordTraining, false);
      AOTCodeCache::disable_caching();
    }
  }
  
  void CDSConfig::prepare_for_dumping() {
    assert(CDSConfig::is_dumping_archive(), "sanity");
--- 769,55 ---
        BytecodeVerificationRemote = true;
        aot_log_info(aot)("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);
+       }
+       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 = !CompilerConfig::is_interpreter_only() && AOTClassLinking && new_aot_flags_used();
+   bool can_use_profile_and_compiled_code = !CompilerConfig::is_interpreter_only() && 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(AOTRecordTraining, true);
      FLAG_SET_ERGO(AOTReplayTraining, false);
      AOTCodeCache::disable_caching(); // No AOT code generation during training run
+     FLAG_SET_ERGO(UseAOTCodeLoadThread, false);
    } else if (is_dumping_final_static_archive() && can_dump_profile_and_compiled_code) {
      // JEP 483 workflow -- assembly
      FLAG_SET_ERGO(AOTRecordTraining, false);
      FLAG_SET_ERGO_IF_DEFAULT(AOTReplayTraining, true);
      AOTCodeCache::enable_caching(); // Generate AOT code during assembly phase.
+     FLAG_SET_ERGO(UseAOTCodeLoadThread, false);
      disable_dumping_aot_code();     // Don't dump AOT code until metadata and heap are dumped.
!   } else if (is_using_archive() && can_use_profile_and_compiled_code) {
      // JEP 483 workflow -- production
      FLAG_SET_ERGO(AOTRecordTraining, false);
      FLAG_SET_ERGO_IF_DEFAULT(AOTReplayTraining, true);
      AOTCodeCache::enable_caching();
+     FLAG_SET_ERGO_IF_DEFAULT(UseAOTCodeLoadThread, true);
+     if (AOTCodeCaching) {
+       FLAG_SET_ERGO_IF_DEFAULT(SkipTier2IfPossible, true);
+     }
    } else {
      FLAG_SET_ERGO(AOTReplayTraining, false);
      FLAG_SET_ERGO(AOTRecordTraining, false);
      AOTCodeCache::disable_caching();
+     FLAG_SET_ERGO(UseAOTCodeLoadThread, false);
    }
  }
  
  void CDSConfig::prepare_for_dumping() {
    assert(CDSConfig::is_dumping_archive(), "sanity");

*** 786,10 ***
--- 862,14 ---
  
  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;
  }
  
  void CDSConfig::enable_dumping_dynamic_archive(const char* output_path) {

*** 807,10 ***
--- 887,14 ---
  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_logging_dynamic_proxies() {
+   return ClassListWriter::is_enabled() || is_dumping_preimage_static_archive();
+ }
+ 
  bool CDSConfig::is_using_archive() {
    return UseSharedSpaces;
  }
  
  bool CDSConfig::is_using_only_default_archive() {

*** 820,11 ***
           strcmp(input_static_archive_path(), default_archive_path()) == 0 &&
           input_dynamic_archive_path() == nullptr;
  }
  
  bool CDSConfig::is_logging_lambda_form_invokers() {
!   return ClassListWriter::is_enabled() || is_dumping_dynamic_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
--- 904,11 ---
           strcmp(input_static_archive_path(), default_archive_path()) == 0 &&
           input_dynamic_archive_path() == nullptr;
  }
  
  bool CDSConfig::is_logging_lambda_form_invokers() {
!   return ClassListWriter::is_enabled() || is_dumping_dynamic_archive() || is_dumping_preimage_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

*** 1025,10 ***
--- 1109,14 ---
    // 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() {

*** 1039,10 ***
--- 1127,15 ---
    // 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_reflection_data() {
+   // reflection data use LambdaForm classes
+   return ArchiveReflectionData && is_dumping_invokedynamic();
+ }
+ 
  // When we are dumping aot-linked classes and we are able to write archived heap objects, we automatically
  // enable the archiving of MethodHandles. This will in turn enable the archiving of MethodTypes and hidden
  // classes that are used in the implementation of MethodHandles.
  // Archived MethodHandles are required for higher-level optimizations such as AOT resolution of invokedynamic
  // and dynamic proxies.
< prev index next >