diff --git a/src/hotspot/share/cds/cdsConfig.cpp b/src/hotspot/share/cds/cdsConfig.cpp
index 6261321fc1fe0..818b92efe70d9 100644
--- a/src/hotspot/share/cds/cdsConfig.cpp
+++ b/src/hotspot/share/cds/cdsConfig.cpp
@@ -27,7 +27,12 @@
 #include "cds/cdsConfig.hpp"
 #include "cds/heapShared.hpp"
 #include "classfile/classLoaderDataShared.hpp"
+#include "classfile/moduleEntry.hpp"
+#include "include/jvm_io.h"
 #include "logging/log.hpp"
+#include "runtime/arguments.hpp"
+#include "runtime/java.hpp"
+#include "utilities/defaultStream.hpp"
 
 bool CDSConfig::_is_dumping_static_archive = false;
 bool CDSConfig::_is_dumping_dynamic_archive = false;
@@ -38,6 +43,318 @@ bool CDSConfig::_is_dumping_dynamic_archive = false;
 bool CDSConfig::_dumping_full_module_graph_disabled = false;
 bool CDSConfig::_loading_full_module_graph_disabled = false;
 
+char* CDSConfig::_default_archive_path = nullptr;
+char* CDSConfig::_static_archive_path = nullptr;
+char* CDSConfig::_dynamic_archive_path = nullptr;
+
+void CDSConfig::initialize() {
+  if (is_dumping_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
+  // 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() || UseSharedSpaces) {
+    init_shared_archive_paths();
+  }
+}
+
+char* CDSConfig::default_archive_path() {
+  if (_default_archive_path == nullptr) {
+    char jvm_path[JVM_MAXPATHLEN];
+    os::jvm_path(jvm_path, sizeof(jvm_path));
+    char *end = strrchr(jvm_path, *os::file_separator());
+    if (end != nullptr) *end = '\0';
+    size_t jvm_path_len = strlen(jvm_path);
+    size_t file_sep_len = strlen(os::file_separator());
+    const size_t len = jvm_path_len + file_sep_len + 20;
+    _default_archive_path = NEW_C_HEAP_ARRAY(char, len, mtArguments);
+    jio_snprintf(_default_archive_path, len,
+                LP64_ONLY(!UseCompressedOops ? "%s%sclasses_nocoops.jsa":) "%s%sclasses.jsa",
+                jvm_path, os::file_separator());
+  }
+  return _default_archive_path;
+}
+
+int CDSConfig::num_archives(const char* archive_path) {
+  if (archive_path == nullptr) {
+    return 0;
+  }
+  int npaths = 1;
+  char* p = (char*)archive_path;
+  while (*p != '\0') {
+    if (*p == os::path_separator()[0]) {
+      npaths++;
+    }
+    p++;
+  }
+  return npaths;
+}
+
+void CDSConfig::extract_shared_archive_paths(const char* archive_path,
+                                             char** base_archive_path,
+                                             char** top_archive_path) {
+  char* begin_ptr = (char*)archive_path;
+  char* end_ptr = strchr((char*)archive_path, os::path_separator()[0]);
+  if (end_ptr == nullptr || end_ptr == begin_ptr) {
+    vm_exit_during_initialization("Base archive was not specified", archive_path);
+  }
+  size_t len = end_ptr - begin_ptr;
+  char* cur_path = NEW_C_HEAP_ARRAY(char, len + 1, mtInternal);
+  strncpy(cur_path, begin_ptr, len);
+  cur_path[len] = '\0';
+  *base_archive_path = cur_path;
+
+  begin_ptr = ++end_ptr;
+  if (*begin_ptr == '\0') {
+    vm_exit_during_initialization("Top archive was not specified", archive_path);
+  }
+  end_ptr = strchr(begin_ptr, '\0');
+  assert(end_ptr != nullptr, "sanity");
+  len = end_ptr - begin_ptr;
+  cur_path = NEW_C_HEAP_ARRAY(char, len + 1, mtInternal);
+  strncpy(cur_path, begin_ptr, len + 1);
+  *top_archive_path = cur_path;
+}
+
+void CDSConfig::init_shared_archive_paths() {
+  if (ArchiveClassesAtExit != nullptr) {
+    assert(!RecordDynamicDumpInfo, "already checked");
+    if (is_dumping_static_archive()) {
+      vm_exit_during_initialization("-XX:ArchiveClassesAtExit cannot be used with -Xshare:dump");
+    }
+    check_unsupported_dumping_properties();
+
+    if (os::same_files(default_archive_path(), ArchiveClassesAtExit)) {
+      vm_exit_during_initialization(
+        "Cannot specify the default CDS archive for -XX:ArchiveClassesAtExit", default_archive_path());
+    }
+  }
+
+  if (SharedArchiveFile == nullptr) {
+    _static_archive_path = default_archive_path();
+  } else {
+    int archives = num_archives(SharedArchiveFile);
+    assert(archives > 0, "must be");
+
+    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 (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);
+    } else {
+      // SharedArchiveFile may specify one or two files. In case (c), the path for base.jsa
+      // is read from top.jsa
+      //    (a) 1 file:  -XX:SharedArchiveFile=base.jsa
+      //    (b) 2 files: -XX:SharedArchiveFile=base.jsa:top.jsa
+      //    (c) 2 files: -XX:SharedArchiveFile=top.jsa
+      //
+      // However, if either RecordDynamicDumpInfo or ArchiveClassesAtExit is used, we do not
+      // allow cases (b) and (c). Case (b) is already checked above.
+
+      if (archives > 2) {
+        vm_exit_during_initialization(
+          "Cannot have more than 2 archive files specified in the -XX:SharedArchiveFile option");
+      }
+      if (archives == 1) {
+        char* base_archive_path = nullptr;
+        bool success =
+          FileMapInfo::get_base_archive_name_from_header(SharedArchiveFile, &base_archive_path);
+        if (!success) {
+          // 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);
+            _static_archive_path = default_archive_path();
+            SharedArchiveFile = nullptr;
+          } else {
+            if (AutoCreateSharedArchive) {
+              warning("-XX:+AutoCreateSharedArchive is unsupported when base CDS archive is not loaded. Run with -Xlog:cds for more info.");
+              AutoCreateSharedArchive = false;
+            }
+            Arguments::no_shared_spaces("invalid archive");
+          }
+        } else if (base_archive_path == nullptr) {
+          // User has specified a single archive, which is a static archive.
+          _static_archive_path = const_cast<char *>(SharedArchiveFile);
+        } else {
+          // User has specified a single archive, which is a dynamic archive.
+          _dynamic_archive_path = const_cast<char *>(SharedArchiveFile);
+          _static_archive_path = base_archive_path; // has been c-heap allocated.
+        }
+      } else {
+        extract_shared_archive_paths((const char*)SharedArchiveFile,
+                                      &_static_archive_path, &_dynamic_archive_path);
+        if (_static_archive_path == nullptr) {
+          assert(_dynamic_archive_path == nullptr, "must be");
+          Arguments::no_shared_spaces("invalid archive");
+        }
+      }
+
+      if (_dynamic_archive_path != nullptr) {
+        // Check for case (c)
+        if (RecordDynamicDumpInfo) {
+          vm_exit_during_initialization("-XX:+RecordDynamicDumpInfo is unsupported when a dynamic CDS archive is specified in -XX:SharedArchiveFile",
+                                        SharedArchiveFile);
+        }
+        if (ArchiveClassesAtExit != nullptr) {
+          vm_exit_during_initialization("-XX:ArchiveClassesAtExit is unsupported when a dynamic CDS archive is specified in -XX:SharedArchiveFile",
+                                        SharedArchiveFile);
+        }
+      }
+
+      if (ArchiveClassesAtExit != nullptr && os::same_files(SharedArchiveFile, ArchiveClassesAtExit)) {
+          vm_exit_during_initialization(
+            "Cannot have the same archive file specified for -XX:SharedArchiveFile and -XX:ArchiveClassesAtExit",
+            SharedArchiveFile);
+      }
+    }
+  }
+}
+
+void CDSConfig::check_system_property(const char* key, const char* value) {
+  if (Arguments::is_internal_module_property(key)) {
+    MetaspaceShared::disable_optimized_module_handling();
+    log_info(cds)("optimized module handling: disabled due to incompatible property: %s=%s", key, value);
+  }
+  if (strcmp(key, "jdk.module.showModuleResolution") == 0 ||
+      strcmp(key, "jdk.module.validation") == 0 ||
+      strcmp(key, "java.system.class.loader") == 0) {
+    disable_loading_full_module_graph();
+    disable_dumping_full_module_graph();
+    log_info(cds)("full module graph: disabled due to incompatible property: %s=%s", key, value);
+  }
+}
+
+static const char* unsupported_properties[] = {
+  "jdk.module.limitmods",
+  "jdk.module.upgrade.path",
+  "jdk.module.patch.0"
+};
+static const char* unsupported_options[] = {
+  "--limit-modules",
+  "--upgrade-module-path",
+  "--patch-module"
+};
+
+void CDSConfig::check_unsupported_dumping_properties() {
+  assert(is_dumping_archive(), "this function is only used with CDS dump time");
+  assert(ARRAY_SIZE(unsupported_properties) == ARRAY_SIZE(unsupported_options), "must be");
+  // If a vm option is found in the unsupported_options array, vm will exit with an error message.
+  SystemProperty* sp = Arguments::system_properties();
+  while (sp != nullptr) {
+    for (uint i = 0; i < ARRAY_SIZE(unsupported_properties); i++) {
+      if (strcmp(sp->key(), unsupported_properties[i]) == 0) {
+        vm_exit_during_initialization(
+          "Cannot use the following option when dumping the shared archive", unsupported_options[i]);
+      }
+    }
+    sp = sp->next();
+  }
+
+  // Check for an exploded module build in use with -Xshare:dump.
+  if (!Arguments::has_jimage()) {
+    vm_exit_during_initialization("Dumping the shared archive is not supported with an exploded module build");
+  }
+}
+
+bool CDSConfig::check_unsupported_cds_runtime_properties() {
+  assert(UseSharedSpaces, "this function is only used with -Xshare:{on,auto}");
+  assert(ARRAY_SIZE(unsupported_properties) == ARRAY_SIZE(unsupported_options), "must be");
+  if (ArchiveClassesAtExit != nullptr) {
+    // dynamic dumping, just return false for now.
+    // check_unsupported_dumping_properties() will be called later to check the same set of
+    // properties, and will exit the VM with the correct error message if the unsupported properties
+    // are used.
+    return false;
+  }
+  for (uint i = 0; i < ARRAY_SIZE(unsupported_properties); i++) {
+    if (Arguments::get_property(unsupported_properties[i]) != nullptr) {
+      if (RequireSharedSpaces) {
+        warning("CDS is disabled when the %s option is specified.", unsupported_options[i]);
+      } else {
+        log_info(cds)("CDS is disabled when the %s option is specified.", unsupported_options[i]);
+      }
+      return true;
+    }
+  }
+  return false;
+}
+
+bool CDSConfig::check_vm_args_consistency(bool patch_mod_javabase,  bool mode_flag_cmd_line) {
+  if (is_dumping_static_archive()) {
+    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
+      // -Xshare:dump -Xmixed to improve dumping speed.
+      Arguments::set_mode_flags(Arguments::_int);
+    } else if (Arguments::mode() == Arguments::_comp) {
+      // -Xcomp may use excessive CPU for the test tiers. Also, -Xshare:dump runs a small and fixed set of
+      // Java code, so there's not much benefit in running -Xcomp.
+      log_info(cds)("reduced -Xcomp to -Xmixed for static dumping");
+      Arguments::set_mode_flags(Arguments::_mixed);
+    }
+
+    // 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;
+  }
+
+  // RecordDynamicDumpInfo is not compatible with ArchiveClassesAtExit
+  if (ArchiveClassesAtExit != nullptr && RecordDynamicDumpInfo) {
+    jio_fprintf(defaultStream::output_stream(),
+                "-XX:+RecordDynamicDumpInfo cannot be used with -XX:ArchiveClassesAtExit.\n");
+    return false;
+  }
+
+  if (ArchiveClassesAtExit == nullptr && !RecordDynamicDumpInfo) {
+    disable_dumping_dynamic_archive();
+  } else {
+    enable_dumping_dynamic_archive();
+  }
+
+  if (AutoCreateSharedArchive) {
+    if (SharedArchiveFile == nullptr) {
+      log_warning(cds)("-XX:+AutoCreateSharedArchive requires -XX:SharedArchiveFile");
+      return false;
+    }
+    if (ArchiveClassesAtExit != nullptr) {
+      log_warning(cds)("-XX:+AutoCreateSharedArchive does not work with ArchiveClassesAtExit");
+      return false;
+    }
+  }
+
+  if (UseSharedSpaces && patch_mod_javabase) {
+    Arguments::no_shared_spaces("CDS is disabled when " JAVA_BASE_NAME " module is patched.");
+  }
+  if (UseSharedSpaces && check_unsupported_cds_runtime_properties()) {
+    UseSharedSpaces = false;
+  }
+
+  if (is_dumping_archive()) {
+    // Always verify non-system classes during CDS dump
+    if (!BytecodeVerificationRemote) {
+      BytecodeVerificationRemote = true;
+      log_info(cds)("All non-system classes will be verified (-Xverify:remote) during CDS dump time.");
+    }
+  }
+
+  return true;
+}
+
 #if INCLUDE_CDS_JAVA_HEAP
 bool CDSConfig::is_dumping_heap() {
   // heap dump is not supported in dynamic dump
diff --git a/src/hotspot/share/cds/cdsConfig.hpp b/src/hotspot/share/cds/cdsConfig.hpp
index cc3c5556d0abe..d7de147d20cf5 100644
--- a/src/hotspot/share/cds/cdsConfig.hpp
+++ b/src/hotspot/share/cds/cdsConfig.hpp
@@ -26,6 +26,7 @@
 #define SHARE_CDS_CDSCONFIG_HPP
 
 #include "memory/allStatic.hpp"
+#include "utilities/globalDefinitions.hpp"
 #include "utilities/macros.hpp"
 
 class CDSConfig : public AllStatic {
@@ -34,9 +35,25 @@ class CDSConfig : public AllStatic {
   static bool _is_dumping_dynamic_archive;
   static bool _dumping_full_module_graph_disabled;
   static bool _loading_full_module_graph_disabled;
+
+  static char*  _default_archive_path;
+  static char*  _static_archive_path;
+  static char*  _dynamic_archive_path;
 #endif
 
+  static void extract_shared_archive_paths(const char* archive_path,
+                                           char** base_archive_path,
+                                           char** top_archive_path);
+  static void init_shared_archive_paths();
+  static bool check_unsupported_cds_runtime_properties();
+
 public:
+  // Initialization and command-line checking
+  static void initialize() NOT_CDS_RETURN;
+  static void check_system_property(const char* key, const char* value) NOT_CDS_RETURN;
+  static void check_unsupported_dumping_properties() NOT_CDS_RETURN;
+  static bool check_vm_args_consistency(bool patch_mod_javabase,  bool mode_flag_cmd_line) NOT_CDS_RETURN_(false);
+
   // Basic CDS features
   static bool      is_dumping_archive()                      { return is_dumping_static_archive() || is_dumping_dynamic_archive(); }
   static bool      is_dumping_static_archive()               { return CDS_ONLY(_is_dumping_static_archive) NOT_CDS(false); }
@@ -45,6 +62,17 @@ class CDSConfig : public AllStatic {
   static void  enable_dumping_dynamic_archive()              { CDS_ONLY(_is_dumping_dynamic_archive = true); }
   static void disable_dumping_dynamic_archive()              { CDS_ONLY(_is_dumping_dynamic_archive = false); }
 
+  // Archive paths
+  // Points to the classes.jsa in $JAVA_HOME
+  static char* default_archive_path()                         NOT_CDS_RETURN_(nullptr);
+  // The actual static archive  (if any) selected at runtime
+  static const char* static_archive_path()                   { return CDS_ONLY(_static_archive_path) NOT_CDS(nullptr); }
+  // The actual dynamic archive  (if any) selected at runtime
+  static const char* dynamic_archive_path()                  { return CDS_ONLY(_dynamic_archive_path) NOT_CDS(nullptr); }
+
+  static int num_archives(const char* archive_path)          NOT_CDS_RETURN_(0);
+
+
   // CDS archived heap
   static bool      is_dumping_heap()                         NOT_CDS_JAVA_HEAP_RETURN_(false);
   static void disable_dumping_full_module_graph(const char* reason = nullptr) NOT_CDS_JAVA_HEAP_RETURN;
diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp
index 0810c17c00a75..99acbb4ace8f2 100644
--- a/src/hotspot/share/cds/filemap.cpp
+++ b/src/hotspot/share/cds/filemap.cpp
@@ -162,8 +162,8 @@ void FileMapInfo::populate_header(size_t core_region_alignment) {
     c_header_size = sizeof(DynamicArchiveHeader);
     header_size = c_header_size;
 
-    const char* default_base_archive_name = Arguments::get_default_shared_archive_path();
-    const char* current_base_archive_name = Arguments::GetSharedArchivePath();
+    const char* default_base_archive_name = CDSConfig::default_archive_path();
+    const char* current_base_archive_name = CDSConfig::static_archive_path();
     if (!os::same_files(current_base_archive_name, default_base_archive_name)) {
       base_archive_name_size = strlen(current_base_archive_name) + 1;
       header_size += base_archive_name_size;
@@ -199,7 +199,7 @@ void FileMapHeader::populate(FileMapInfo *info, size_t core_region_alignment,
 
   if (!info->is_static() && base_archive_name_size != 0) {
     // copy base archive name
-    copy_base_archive_name(Arguments::GetSharedArchivePath());
+    copy_base_archive_name(CDSConfig::static_archive_path());
   }
   _core_region_alignment = core_region_alignment;
   _obj_alignment = ObjectAlignmentInBytes;
@@ -918,7 +918,7 @@ void FileMapInfo::log_paths(const char* msg, int start_idx, int end_idx) {
 
 bool FileMapInfo::check_module_paths() {
   const char* rp = Arguments::get_property("jdk.module.path");
-  int num_paths = Arguments::num_archives(rp);
+  int num_paths = CDSConfig::num_archives(rp);
   if (num_paths != header()->num_module_paths()) {
     return false;
   }
@@ -1250,7 +1250,7 @@ bool FileMapInfo::get_base_archive_name_from_header(const char* archive_name,
 
   const char* base = file_helper.base_archive_name();
   if (base == nullptr) {
-    *base_archive_name = Arguments::get_default_shared_archive_path();
+    *base_archive_name = CDSConfig::default_archive_path();
   } else {
     *base_archive_name = os::strdup_check_oom(base);
   }
@@ -2275,7 +2275,7 @@ bool FileMapInfo::initialize() {
       log_info(cds)("Initialize dynamic archive failed.");
       if (AutoCreateSharedArchive) {
         CDSConfig::enable_dumping_dynamic_archive();
-        ArchiveClassesAtExit = Arguments::GetSharedDynamicArchivePath();
+        ArchiveClassesAtExit = CDSConfig::dynamic_archive_path();
       }
       return false;
     }
diff --git a/src/hotspot/share/cds/metaspaceShared.cpp b/src/hotspot/share/cds/metaspaceShared.cpp
index dedd7cb85ee5d..fedbc5841b682 100644
--- a/src/hotspot/share/cds/metaspaceShared.cpp
+++ b/src/hotspot/share/cds/metaspaceShared.cpp
@@ -539,7 +539,7 @@ void VM_PopulateDumpSharedSpace::doit() {
   builder.relocate_to_requested();
 
   // Write the archive file
-  const char* static_archive = Arguments::GetSharedArchivePath();
+  const char* static_archive = CDSConfig::static_archive_path();
   assert(static_archive != nullptr, "SharedArchiveFile not set?");
   FileMapInfo* mapinfo = new FileMapInfo(static_archive, true);
   mapinfo->populate_header(MetaspaceShared::core_region_alignment());
@@ -651,8 +651,7 @@ void MetaspaceShared::link_shared_classes(bool jcmd_request, TRAPS) {
 
 void MetaspaceShared::prepare_for_dumping() {
   assert(CDSConfig::is_dumping_archive(), "sanity");
-  Arguments::check_unsupported_dumping_properties();
-
+  CDSConfig::check_unsupported_dumping_properties();
   ClassLoader::initialize_shared_path(JavaThread::current());
 }
 
@@ -987,8 +986,8 @@ void MetaspaceShared::initialize_runtime_shared_and_meta_spaces() {
 }
 
 FileMapInfo* MetaspaceShared::open_static_archive() {
-  const char* static_archive = Arguments::GetSharedArchivePath();
-  assert(static_archive != nullptr, "SharedArchivePath is nullptr");
+  const char* static_archive = CDSConfig::static_archive_path();
+  assert(static_archive != nullptr, "sanity");
   FileMapInfo* mapinfo = new FileMapInfo(static_archive, true);
   if (!mapinfo->initialize()) {
     delete(mapinfo);
@@ -1001,7 +1000,7 @@ FileMapInfo* MetaspaceShared::open_dynamic_archive() {
   if (CDSConfig::is_dumping_dynamic_archive()) {
     return nullptr;
   }
-  const char* dynamic_archive = Arguments::GetSharedDynamicArchivePath();
+  const char* dynamic_archive = CDSConfig::dynamic_archive_path();
   if (dynamic_archive == nullptr) {
     return nullptr;
   }
@@ -1494,7 +1493,7 @@ void MetaspaceShared::initialize_shared_spaces() {
   if (PrintSharedArchiveAndExit) {
     // Print archive names
     if (dynamic_mapinfo != nullptr) {
-      tty->print_cr("\n\nBase archive name: %s", Arguments::GetSharedArchivePath());
+      tty->print_cr("\n\nBase archive name: %s", CDSConfig::static_archive_path());
       tty->print_cr("Base archive version %d", static_mapinfo->version());
     } else {
       tty->print_cr("Static archive name: %s", static_mapinfo->full_path());
diff --git a/src/hotspot/share/prims/whitebox.cpp b/src/hotspot/share/prims/whitebox.cpp
index 230129ea2df31..d70c775937fd0 100644
--- a/src/hotspot/share/prims/whitebox.cpp
+++ b/src/hotspot/share/prims/whitebox.cpp
@@ -2043,7 +2043,7 @@ WB_ENTRY(jobject, WB_GetMethodStringOption(JNIEnv* env, jobject wb, jobject meth
 WB_END
 
 WB_ENTRY(jobject, WB_GetDefaultArchivePath(JNIEnv* env, jobject wb))
-  const char* p = Arguments::get_default_shared_archive_path();
+  const char* p = CDSConfig::default_archive_path();
   ThreadToNativeFromVM ttn(thread);
   jstring path_string = env->NewStringUTF(p);
 
diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp
index 477a1ebe8d110..fd8f155af420e 100644
--- a/src/hotspot/share/runtime/arguments.cpp
+++ b/src/hotspot/share/runtime/arguments.cpp
@@ -101,10 +101,6 @@ size_t Arguments::_default_SharedBaseAddress    = SharedBaseAddress;
 
 bool   Arguments::_enable_preview               = false;
 
-char*  Arguments::_default_shared_archive_path  = nullptr;
-char*  Arguments::SharedArchivePath             = nullptr;
-char*  Arguments::SharedDynamicArchivePath      = nullptr;
-
 LegacyGCLogging Arguments::_legacyGCLogging     = { 0, 0 };
 
 // These are not set by the JDK's built-in launchers, but they can be set by
@@ -1263,19 +1259,7 @@ bool Arguments::add_property(const char* prop, PropertyWriteable writeable, Prop
     value = &prop[key_len + 1];
   }
 
-#if INCLUDE_CDS
-  if (is_internal_module_property(key)) {
-    MetaspaceShared::disable_optimized_module_handling();
-    log_info(cds)("optimized module handling: disabled due to incompatible property: %s=%s", key, value);
-  }
-  if (strcmp(key, "jdk.module.showModuleResolution") == 0 ||
-      strcmp(key, "jdk.module.validation") == 0 ||
-      strcmp(key, "java.system.class.loader") == 0) {
-    CDSConfig::disable_loading_full_module_graph();
-    CDSConfig::disable_dumping_full_module_graph();
-    log_info(cds)("full module graph: disabled due to incompatible property: %s=%s", key, value);
-  }
-#endif
+  CDSConfig::check_system_property(key, value);
 
   if (strcmp(key, "java.compiler") == 0) {
     // we no longer support java.compiler system property, log a warning and let it get
@@ -1329,60 +1313,6 @@ bool Arguments::add_property(const char* prop, PropertyWriteable writeable, Prop
   return true;
 }
 
-#if INCLUDE_CDS
-const char* unsupported_properties[] = { "jdk.module.limitmods",
-                                         "jdk.module.upgrade.path",
-                                         "jdk.module.patch.0" };
-const char* unsupported_options[] = { "--limit-modules",
-                                      "--upgrade-module-path",
-                                      "--patch-module"
-                                    };
-void Arguments::check_unsupported_dumping_properties() {
-  assert(CDSConfig::is_dumping_archive(),
-         "this function is only used with CDS dump time");
-  assert(ARRAY_SIZE(unsupported_properties) == ARRAY_SIZE(unsupported_options), "must be");
-  // If a vm option is found in the unsupported_options array, vm will exit with an error message.
-  SystemProperty* sp = system_properties();
-  while (sp != nullptr) {
-    for (uint i = 0; i < ARRAY_SIZE(unsupported_properties); i++) {
-      if (strcmp(sp->key(), unsupported_properties[i]) == 0) {
-        vm_exit_during_initialization(
-          "Cannot use the following option when dumping the shared archive", unsupported_options[i]);
-      }
-    }
-    sp = sp->next();
-  }
-
-  // Check for an exploded module build in use with -Xshare:dump.
-  if (!has_jimage()) {
-    vm_exit_during_initialization("Dumping the shared archive is not supported with an exploded module build");
-  }
-}
-
-bool Arguments::check_unsupported_cds_runtime_properties() {
-  assert(UseSharedSpaces, "this function is only used with -Xshare:{on,auto}");
-  assert(ARRAY_SIZE(unsupported_properties) == ARRAY_SIZE(unsupported_options), "must be");
-  if (ArchiveClassesAtExit != nullptr) {
-    // dynamic dumping, just return false for now.
-    // check_unsupported_dumping_properties() will be called later to check the same set of
-    // properties, and will exit the VM with the correct error message if the unsupported properties
-    // are used.
-    return false;
-  }
-  for (uint i = 0; i < ARRAY_SIZE(unsupported_properties); i++) {
-    if (get_property(unsupported_properties[i]) != nullptr) {
-      if (RequireSharedSpaces) {
-        warning("CDS is disabled when the %s option is specified.", unsupported_options[i]);
-      } else {
-        log_info(cds)("CDS is disabled when the %s option is specified.", unsupported_options[i]);
-      }
-      return true;
-    }
-  }
-  return false;
-}
-#endif
-
 //===========================================================================================================
 // Setting int/mixed/comp mode flags
 
@@ -1432,7 +1362,7 @@ void Arguments::set_mode_flags(Mode mode) {
 
 // Conflict: required to use shared spaces (-Xshare:on), but
 // incompatible command line options were chosen.
-static void no_shared_spaces(const char* message) {
+void Arguments::no_shared_spaces(const char* message) {
   if (RequireSharedSpaces) {
     jio_fprintf(defaultStream::error_stream(),
       "Class data sharing is inconsistent with other specified options.\n");
@@ -3037,67 +2967,10 @@ jint Arguments::finalize_vm_init_args(bool patch_mod_javabase) {
     return JNI_ERR;
   }
 
-#if INCLUDE_CDS
-  if (CDSConfig::is_dumping_static_archive()) {
-    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
-      // -Xshare:dump -Xmixed to improve dumping speed.
-      set_mode_flags(_int);
-    } else if (_mode == _comp) {
-      // -Xcomp may use excessive CPU for the test tiers. Also, -Xshare:dump runs a small and fixed set of
-      // Java code, so there's not much benefit in running -Xcomp.
-      log_info(cds)("reduced -Xcomp to -Xmixed for static dumping");
-      set_mode_flags(_mixed);
-    }
-
-    // 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;
-  }
-
-  // RecordDynamicDumpInfo is not compatible with ArchiveClassesAtExit
-  if (ArchiveClassesAtExit != nullptr && RecordDynamicDumpInfo) {
-    jio_fprintf(defaultStream::output_stream(),
-                "-XX:+RecordDynamicDumpInfo cannot be used with -XX:ArchiveClassesAtExit.\n");
+  if (!CDSConfig::check_vm_args_consistency(patch_mod_javabase, mode_flag_cmd_line)) {
     return JNI_ERR;
   }
 
-  if (ArchiveClassesAtExit == nullptr && !RecordDynamicDumpInfo) {
-    CDSConfig::disable_dumping_dynamic_archive();
-  } else {
-    CDSConfig::enable_dumping_dynamic_archive();
-  }
-
-  if (AutoCreateSharedArchive) {
-    if (SharedArchiveFile == nullptr) {
-      log_warning(cds)("-XX:+AutoCreateSharedArchive requires -XX:SharedArchiveFile");
-      return JNI_ERR;
-    }
-    if (ArchiveClassesAtExit != nullptr) {
-      log_warning(cds)("-XX:+AutoCreateSharedArchive does not work with ArchiveClassesAtExit");
-      return JNI_ERR;
-    }
-  }
-
-  if (UseSharedSpaces && patch_mod_javabase) {
-    no_shared_spaces("CDS is disabled when " JAVA_BASE_NAME " module is patched.");
-  }
-  if (UseSharedSpaces && check_unsupported_cds_runtime_properties()) {
-    UseSharedSpaces = false;
-  }
-
-  if (CDSConfig::is_dumping_archive()) {
-    // Always verify non-system classes during CDS dump
-    if (!BytecodeVerificationRemote) {
-      BytecodeVerificationRemote = true;
-      log_info(cds)("All non-system classes will be verified (-Xverify:remote) during CDS dump time.");
-    }
-  }
-#endif
-
 #ifndef CAN_SHOW_REGISTERS_ON_ASSERT
   UNSUPPORTED_OPTION(ShowRegistersOnAssert);
 #endif // CAN_SHOW_REGISTERS_ON_ASSERT
@@ -3365,187 +3238,6 @@ jint Arguments::parse_options_buffer(const char* name, char* buffer, const size_
   return vm_args->set_args(&options);
 }
 
-void Arguments::set_shared_spaces_flags_and_archive_paths() {
-  if (CDSConfig::is_dumping_static_archive()) {
-    if (RequireSharedSpaces) {
-      warning("Cannot dump shared archive while using shared archive");
-    }
-    UseSharedSpaces = false;
-  }
-#if INCLUDE_CDS
-  // 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.
-  //
-  // UseSharedSpaces may be disabled if -XX:SharedArchiveFile is invalid.
-  if (CDSConfig::is_dumping_static_archive() || UseSharedSpaces) {
-    init_shared_archive_paths();
-  }
-#endif  // INCLUDE_CDS
-}
-
-#if INCLUDE_CDS
-// Sharing support
-// Construct the path to the archive
-char* Arguments::get_default_shared_archive_path() {
-  if (_default_shared_archive_path == nullptr) {
-    char jvm_path[JVM_MAXPATHLEN];
-    os::jvm_path(jvm_path, sizeof(jvm_path));
-    char *end = strrchr(jvm_path, *os::file_separator());
-    if (end != nullptr) *end = '\0';
-    size_t jvm_path_len = strlen(jvm_path);
-    size_t file_sep_len = strlen(os::file_separator());
-    const size_t len = jvm_path_len + file_sep_len + 20;
-    _default_shared_archive_path = NEW_C_HEAP_ARRAY(char, len, mtArguments);
-    jio_snprintf(_default_shared_archive_path, len,
-                LP64_ONLY(!UseCompressedOops ? "%s%sclasses_nocoops.jsa":) "%s%sclasses.jsa",
-                jvm_path, os::file_separator());
-  }
-  return _default_shared_archive_path;
-}
-
-int Arguments::num_archives(const char* archive_path) {
-  if (archive_path == nullptr) {
-    return 0;
-  }
-  int npaths = 1;
-  char* p = (char*)archive_path;
-  while (*p != '\0') {
-    if (*p == os::path_separator()[0]) {
-      npaths++;
-    }
-    p++;
-  }
-  return npaths;
-}
-
-void Arguments::extract_shared_archive_paths(const char* archive_path,
-                                         char** base_archive_path,
-                                         char** top_archive_path) {
-  char* begin_ptr = (char*)archive_path;
-  char* end_ptr = strchr((char*)archive_path, os::path_separator()[0]);
-  if (end_ptr == nullptr || end_ptr == begin_ptr) {
-    vm_exit_during_initialization("Base archive was not specified", archive_path);
-  }
-  size_t len = end_ptr - begin_ptr;
-  char* cur_path = NEW_C_HEAP_ARRAY(char, len + 1, mtInternal);
-  strncpy(cur_path, begin_ptr, len);
-  cur_path[len] = '\0';
-  *base_archive_path = cur_path;
-
-  begin_ptr = ++end_ptr;
-  if (*begin_ptr == '\0') {
-    vm_exit_during_initialization("Top archive was not specified", archive_path);
-  }
-  end_ptr = strchr(begin_ptr, '\0');
-  assert(end_ptr != nullptr, "sanity");
-  len = end_ptr - begin_ptr;
-  cur_path = NEW_C_HEAP_ARRAY(char, len + 1, mtInternal);
-  strncpy(cur_path, begin_ptr, len + 1);
-  *top_archive_path = cur_path;
-}
-
-void Arguments::init_shared_archive_paths() {
-  if (ArchiveClassesAtExit != nullptr) {
-    assert(!RecordDynamicDumpInfo, "already checked");
-    if (CDSConfig::is_dumping_static_archive()) {
-      vm_exit_during_initialization("-XX:ArchiveClassesAtExit cannot be used with -Xshare:dump");
-    }
-    check_unsupported_dumping_properties();
-
-    if (os::same_files(get_default_shared_archive_path(), ArchiveClassesAtExit)) {
-      vm_exit_during_initialization(
-        "Cannot specify the default CDS archive for -XX:ArchiveClassesAtExit", get_default_shared_archive_path());
-    }
-  }
-
-  if (SharedArchiveFile == nullptr) {
-    SharedArchivePath = get_default_shared_archive_path();
-  } else {
-    int archives = num_archives(SharedArchiveFile);
-    assert(archives > 0, "must be");
-
-    if (CDSConfig::is_dumping_archive() && archives > 1) {
-      vm_exit_during_initialization(
-        "Cannot have more than 1 archive file specified in -XX:SharedArchiveFile during CDS dumping");
-    }
-
-    if (CDSConfig::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
-      SharedArchivePath = os::strdup_check_oom(SharedArchiveFile, mtArguments);
-    } else {
-      // SharedArchiveFile may specify one or two files. In case (c), the path for base.jsa
-      // is read from top.jsa
-      //    (a) 1 file:  -XX:SharedArchiveFile=base.jsa
-      //    (b) 2 files: -XX:SharedArchiveFile=base.jsa:top.jsa
-      //    (c) 2 files: -XX:SharedArchiveFile=top.jsa
-      //
-      // However, if either RecordDynamicDumpInfo or ArchiveClassesAtExit is used, we do not
-      // allow cases (b) and (c). Case (b) is already checked above.
-
-      if (archives > 2) {
-        vm_exit_during_initialization(
-          "Cannot have more than 2 archive files specified in the -XX:SharedArchiveFile option");
-      }
-      if (archives == 1) {
-        char* base_archive_path = nullptr;
-        bool success =
-          FileMapInfo::get_base_archive_name_from_header(SharedArchiveFile, &base_archive_path);
-        if (!success) {
-          // If +AutoCreateSharedArchive and the specified shared archive does not exist,
-          // regenerate the dynamic archive base on default archive.
-          if (AutoCreateSharedArchive && !os::file_exists(SharedArchiveFile)) {
-            CDSConfig::enable_dumping_dynamic_archive();
-            ArchiveClassesAtExit = const_cast<char *>(SharedArchiveFile);
-            SharedArchivePath = get_default_shared_archive_path();
-            SharedArchiveFile = nullptr;
-          } else {
-            if (AutoCreateSharedArchive) {
-              warning("-XX:+AutoCreateSharedArchive is unsupported when base CDS archive is not loaded. Run with -Xlog:cds for more info.");
-              AutoCreateSharedArchive = false;
-            }
-            no_shared_spaces("invalid archive");
-          }
-        } else if (base_archive_path == nullptr) {
-          // User has specified a single archive, which is a static archive.
-          SharedArchivePath = const_cast<char *>(SharedArchiveFile);
-        } else {
-          // User has specified a single archive, which is a dynamic archive.
-          SharedDynamicArchivePath = const_cast<char *>(SharedArchiveFile);
-          SharedArchivePath = base_archive_path; // has been c-heap allocated.
-        }
-      } else {
-        extract_shared_archive_paths((const char*)SharedArchiveFile,
-                                      &SharedArchivePath, &SharedDynamicArchivePath);
-        if (SharedArchivePath == nullptr) {
-          assert(SharedDynamicArchivePath == nullptr, "must be");
-          no_shared_spaces("invalid archive");
-        }
-      }
-
-      if (SharedDynamicArchivePath != nullptr) {
-        // Check for case (c)
-        if (RecordDynamicDumpInfo) {
-          vm_exit_during_initialization("-XX:+RecordDynamicDumpInfo is unsupported when a dynamic CDS archive is specified in -XX:SharedArchiveFile",
-                                        SharedArchiveFile);
-        }
-        if (ArchiveClassesAtExit != nullptr) {
-          vm_exit_during_initialization("-XX:ArchiveClassesAtExit is unsupported when a dynamic CDS archive is specified in -XX:SharedArchiveFile",
-                                        SharedArchiveFile);
-        }
-      }
-
-      if (ArchiveClassesAtExit != nullptr && os::same_files(SharedArchiveFile, ArchiveClassesAtExit)) {
-          vm_exit_during_initialization(
-            "Cannot have the same archive file specified for -XX:SharedArchiveFile and -XX:ArchiveClassesAtExit",
-            SharedArchiveFile);
-      }
-    }
-  }
-}
-#endif // INCLUDE_CDS
-
 #ifndef PRODUCT
 // Determine whether LogVMOutput should be implicitly turned on.
 static bool use_vm_log() {
@@ -3990,7 +3682,7 @@ jint Arguments::apply_ergo() {
 
   GCConfig::arguments()->initialize();
 
-  set_shared_spaces_flags_and_archive_paths();
+  CDSConfig::initialize();
 
   // Initialize Metaspace flags and alignments
   Metaspace::ergo_initialize();
diff --git a/src/hotspot/share/runtime/arguments.hpp b/src/hotspot/share/runtime/arguments.hpp
index 2b871fdc0c96c..8251db3d0d59a 100644
--- a/src/hotspot/share/runtime/arguments.hpp
+++ b/src/hotspot/share/runtime/arguments.hpp
@@ -248,7 +248,6 @@ class Arguments : AllStatic {
 
   // Operation modi
   static Mode _mode;
-  static void set_mode_flags(Mode mode);
 
   // preview features
   static bool _enable_preview;
@@ -264,7 +263,6 @@ class Arguments : AllStatic {
   static void set_use_compressed_oops();
   static void set_use_compressed_klass_ptrs();
   static jint set_ergonomics_flags();
-  static void set_shared_spaces_flags_and_archive_paths();
   // Limits the given heap size by the maximum amount of virtual
   // memory this process is currently allowed to use. It also takes
   // the virtual-to-physical ratio of the current GC into account.
@@ -363,17 +361,9 @@ class Arguments : AllStatic {
   // Return the "real" name for option arg if arg is an alias, and print a warning if arg is deprecated.
   // Return nullptr if the arg has expired.
   static const char* handle_aliases_and_deprecation(const char* arg);
-
-  static char*  _default_shared_archive_path;
-  static char*  SharedArchivePath;
-  static char*  SharedDynamicArchivePath;
   static size_t _default_SharedBaseAddress; // The default value specified in globals.hpp
-  static void extract_shared_archive_paths(const char* archive_path,
-                                         char** base_archive_path,
-                                         char** top_archive_path) NOT_CDS_RETURN;
 
  public:
-  static int num_archives(const char* archive_path) NOT_CDS_RETURN_(0);
   // Parses the arguments, first phase
   static jint parse(const JavaVMInitArgs* args);
   // Parse a string for a unsigned integer.  Returns true if value
@@ -441,8 +431,7 @@ class Arguments : AllStatic {
   static exit_hook_t     exit_hook()        { return _exit_hook; }
   static vfprintf_hook_t vfprintf_hook()    { return _vfprintf_hook; }
 
-  static const char* GetSharedArchivePath() { return SharedArchivePath; }
-  static const char* GetSharedDynamicArchivePath() { return SharedDynamicArchivePath; }
+  static void no_shared_spaces(const char* message);
   static size_t default_SharedBaseAddress() { return _default_SharedBaseAddress; }
   // Java launcher properties
   static void process_sun_java_launcher_properties(JavaVMInitArgs* args);
@@ -501,11 +490,9 @@ class Arguments : AllStatic {
   static char* get_appclasspath() { return _java_class_path->value(); }
   static void  fix_appclasspath();
 
-  static char* get_default_shared_archive_path() NOT_CDS_RETURN_(nullptr);
-  static void  init_shared_archive_paths() NOT_CDS_RETURN;
-
   // Operation modi
   static Mode mode()                { return _mode;           }
+  static void set_mode_flags(Mode mode);
   static bool is_interpreter_only() { return mode() == _int;  }
   static bool is_compiler_only()    { return mode() == _comp; }
 
@@ -517,10 +504,6 @@ class Arguments : AllStatic {
   // Utility: copies src into buf, replacing "%%" with "%" and "%p" with pid.
   static bool copy_expand_pid(const char* src, size_t srclen, char* buf, size_t buflen);
 
-  static void check_unsupported_dumping_properties() NOT_CDS_RETURN;
-
-  static bool check_unsupported_cds_runtime_properties() NOT_CDS_RETURN0;
-
   static bool atojulong(const char *s, julong* result);
 
   static bool has_jfr_option() NOT_JFR_RETURN_(false);
diff --git a/src/jdk.hotspot.agent/share/native/libsaproc/ps_core_common.c b/src/jdk.hotspot.agent/share/native/libsaproc/ps_core_common.c
index 3912332662ae1..bcce23f12216a 100644
--- a/src/jdk.hotspot.agent/share/native/libsaproc/ps_core_common.c
+++ b/src/jdk.hotspot.agent/share/native/libsaproc/ps_core_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -264,16 +264,16 @@ bool read_string(struct ps_prochandle* ph, uintptr_t addr, char* buf, size_t siz
 }
 
 #ifdef LINUX
-// mangled name of Arguments::SharedArchivePath
-#define SHARED_ARCHIVE_PATH_SYM "_ZN9Arguments17SharedArchivePathE"
+// mangled name of CDSConfig::_static_archive_path
+#define SHARED_ARCHIVE_PATH_SYM "_ZN9CDSConfig20_static_archive_pathE"
 #define USE_SHARED_SPACES_SYM "UseSharedSpaces"
 #define SHARED_BASE_ADDRESS_SYM "SharedBaseAddress"
 #define LIBJVM_NAME "/libjvm.so"
 #endif
 
 #ifdef __APPLE__
-// mangled name of Arguments::SharedArchivePath
-#define SHARED_ARCHIVE_PATH_SYM "__ZN9Arguments17SharedArchivePathE"
+// mangled name of CDSConfig::_static_archive_path
+#define SHARED_ARCHIVE_PATH_SYM "__ZN9CDSConfig20_static_archive_pathE"
 #define USE_SHARED_SPACES_SYM "_UseSharedSpaces"
 #define SHARED_BASE_ADDRESS_SYM "_SharedBaseAddress"
 #define LIBJVM_NAME "/libjvm.dylib"