From 4ed0d3fb36e543e65fd259300ded4e2bbe0f6c18 Mon Sep 17 00:00:00 2001
Date: Sat, 16 May 2026 11:41:45 +0800
Subject: Add Aggresive CDS and bugfix

---
 make/data/hotspot-symbols/symbols-unix        |   1 +
 src/hotspot/cpu/aarch64/globals_aarch64.hpp   |   9 +-
 .../javaThread_linux_aarch64.cpp              | 208 ++++++++++++++
 .../javaThread_linux_aarch64.hpp              |   2 +
 src/hotspot/share/cds/cdsConstants.cpp        |   3 +
 src/hotspot/share/cds/cds_globals.hpp         |  28 +-
 src/hotspot/share/cds/dumpTimeClassInfo.cpp   |  27 ++
 src/hotspot/share/cds/dumpTimeClassInfo.hpp   |  68 +++++
 src/hotspot/share/cds/dynamicArchive.cpp      |  57 ++++
 src/hotspot/share/cds/dynamicArchive.hpp      |   8 +
 src/hotspot/share/cds/filemap.cpp             |  48 +++-
 src/hotspot/share/cds/metaspaceShared.cpp     |   2 +-
 src/hotspot/share/cds/runTimeClassInfo.cpp    | 109 ++++++++
 src/hotspot/share/cds/runTimeClassInfo.hpp    |  72 +++++
 src/hotspot/share/classfile/classLoader.cpp   |   2 +-
 src/hotspot/share/classfile/javaClasses.cpp   |  40 +++
 src/hotspot/share/classfile/javaClasses.hpp   |  26 ++
 src/hotspot/share/classfile/klassFactory.cpp  |  53 +++-
 .../classfile/systemDictionaryShared.cpp      | 263 ++++++++++++++++++
 .../classfile/systemDictionaryShared.hpp      |  17 ++
 src/hotspot/share/classfile/vmSymbols.hpp     |   3 +
 src/hotspot/share/include/cds.h               |   1 +
 src/hotspot/share/include/jvm.h               |   5 +
 src/hotspot/share/logging/logTag.hpp          |   1 +
 src/hotspot/share/oops/instanceKlass.cpp      |  24 ++
 src/hotspot/share/oops/instanceKlass.hpp      |   7 +
 .../share/oops/instanceKlass.inline.hpp       |  15 +
 src/hotspot/share/prims/jvm.cpp               |  21 ++
 src/hotspot/share/runtime/arguments.cpp       |  60 +++-
 src/hotspot/share/runtime/arguments.hpp       |   5 +
 src/hotspot/share/runtime/threads.cpp         |   2 +
 src/hotspot/share/utilities/macros.hpp        |  14 +
 .../share/classes/java/lang/ClassLoader.java  |  20 ++
 .../classes/java/net/AggressiveCDSPlugin.java | 203 ++++++++++++++
 .../classes/java/net/URLClassLoader.java      |  30 ++
 .../java/security/SecureClassLoader.java      |  14 +
 .../jdk/internal/loader/URLClassPath.java     |  18 ++
 .../share/native/libjava/ClassLoader.c        |  26 ++
 38 files changed, 1483 insertions(+), 29 deletions(-)
 create mode 100644 src/java.base/share/classes/java/net/AggressiveCDSPlugin.java

diff --git a/make/data/hotspot-symbols/symbols-unix b/make/data/hotspot-symbols/symbols-unix
index 5cf6662cb..2a407b283 100644
--- a/make/data/hotspot-symbols/symbols-unix
+++ b/make/data/hotspot-symbols/symbols-unix
@@ -216,6 +216,7 @@ JVM_AddReadsModule
 JVM_DefineArchivedModules
 JVM_DefineModule
 JVM_SetBootLoaderUnnamedModule
+JVM_DefineTrustedSharedClass
 
 # Virtual thread notifications for JVMTI
 JVM_VirtualThreadStart
diff --git a/src/hotspot/cpu/aarch64/globals_aarch64.hpp b/src/hotspot/cpu/aarch64/globals_aarch64.hpp
index ef9833629..758034ba4 100644
--- a/src/hotspot/cpu/aarch64/globals_aarch64.hpp
+++ b/src/hotspot/cpu/aarch64/globals_aarch64.hpp
@@ -203,7 +203,7 @@ define_pd_global(intx, InlineSmallCode,          1000);
   product(bool, LogNUMANodes, false,                                    \
           "Print NUMANodes")                                            \
                                                                         \
-  product(ccstr, NUMANodes, NULL,                                       \
+  product(ccstr, NUMANodes, nullptr,                                    \
           "This parameter provides the same functionality as"           \
           "'numactl --all -N <nodes> -m <nodes>'."                      \
           "<nodes> can be '0-2', '0,1,2', 'all' and so on.")            \
@@ -216,13 +216,18 @@ define_pd_global(intx, InlineSmallCode,          1000);
   product(intx, NUMAMemNodesRandom, 0,                                  \
           "Number of continuous nodes to bind to memory"                \
           "with the first N nodes chosen by NUMANodesRandom.")          \
-  product(ccstr, NUMABindPolicy, NULL,                                  \
+  product(ccstr, NUMABindPolicy, nullptr,                               \
           "Enable deterministic NUMA placement with combined Options,"  \
           "including prefix=<id> and div=<N>.")                         \
   product(bool, UseStlrForRelease, false,                               \
           "Use stlr instead of dmb ish + str for release stores")       \
   product(bool, UseUTFConversionIntrinsics, false,                      \
           "Use Intrinsics for conversion between UTF8 and UTF16")       \
+  product(ccstr, AutoSharedArchivePath, nullptr,                        \
+          "Auto enable the AppCDS feature"                              \
+          "the path save classlist and jsa file")                       \
+  product(bool, PrintAutoAppCDS, false,                                 \
+          "Print path and some information about AutoSharedArchivePath")\
 
 // end of ARCH_FLAGS
 
diff --git a/src/hotspot/os_cpu/linux_aarch64/javaThread_linux_aarch64.cpp b/src/hotspot/os_cpu/linux_aarch64/javaThread_linux_aarch64.cpp
index 533151096..96fc76ebf 100644
--- a/src/hotspot/os_cpu/linux_aarch64/javaThread_linux_aarch64.cpp
+++ b/src/hotspot/os_cpu/linux_aarch64/javaThread_linux_aarch64.cpp
@@ -23,9 +23,17 @@
  *
  */
 
+#include "os_linux.inline.hpp"
 #include "precompiled.hpp"
+#include "runtime/arguments.hpp"
 #include "runtime/frame.inline.hpp"
+#include "runtime/globals.hpp"
+#include "runtime/globals_extension.hpp"
+#include "runtime/java.hpp"
 #include "runtime/javaThread.hpp"
+#include "runtime/thread.inline.hpp"
+
+#include <sys/file.h>
 
 frame JavaThread::pd_last_frame() {
   assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
@@ -92,3 +100,203 @@ bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava)
 }
 
 void JavaThread::cache_global_variables() { }
+
+static char* get_java_executable_path() {
+  const char* java_home = Arguments::get_property("java.home");
+  if (java_home != nullptr) {
+    char* path = NEW_C_HEAP_ARRAY(char, MAXPATHLEN, mtInternal);
+    jio_snprintf(path, MAXPATHLEN, "%s/bin/java", java_home);
+    return path;
+  }
+  return os::strdup("java");
+}
+
+static char* get_complete_classpath() {
+  const char* env_cp = Arguments::get_property("env.class.path");
+  if (env_cp == nullptr || env_cp[0] == '\0') {
+    env_cp = ::getenv("CLASSPATH");
+  }
+  return (char *)env_cp;
+}
+
+static bool can_read_classlist(const char* class_list_path) {
+  int fd = open(class_list_path, O_RDWR | O_CREAT, 0644);
+  if (fd < 0) return false;
+  return flock(fd, LOCK_EX | LOCK_NB) == 0;
+}
+
+static void construct_path(char *dest, size_t dest_size, const char *base, const char *suffix) {
+  size_t base_len = strlen(base);
+  size_t suffix_len = strlen(suffix);
+  guarantee(base_len + suffix_len < dest_size, "base path too long!");
+
+  jio_snprintf(dest, dest_size, "%s%s", base, suffix);
+}
+
+static void create_jsa(const char* class_list_path, const char* appcds_path, const JavaVMInitArgs* original_args) {
+  pid_t pid = fork();
+  if (pid == 0) {
+    // child process running on background
+    setsid();
+    signal(SIGHUP, SIG_IGN);
+    const char* classpath = get_complete_classpath();
+    if (classpath == nullptr) {
+      classpath = ".";
+    }
+    char* java_path = get_java_executable_path();
+    int arg_count = Arguments::num_jvm_args();
+    char** vm_args  = Arguments::jvm_args_array();
+
+    int total_args = arg_count + 9;
+    char** args = NEW_C_HEAP_ARRAY(char*, total_args + 1, mtInternal);
+    int idx = 0;
+
+    args[idx++] = java_path;
+    args[idx++] = os::strdup("-Xshare:dump");
+    args[idx++] = os::strdup("-XX:+UnlockDiagnosticVMOptions");
+    args[idx++] = os::strdup("-XX:+SkipSharedClassPathCheck");
+
+    char shared_class_list_file[PATH_MAX];
+    construct_path(shared_class_list_file, sizeof(shared_class_list_file), "-XX:SharedClassListFile=", class_list_path);
+    args[idx++] = os::strdup(shared_class_list_file);
+
+    char shared_archive_file[PATH_MAX];
+    construct_path(shared_archive_file, sizeof(shared_archive_file), "-XX:SharedArchiveFile=", appcds_path);
+    args[idx++] = os::strdup(shared_archive_file);
+
+    args[idx++] = os::strdup("-classpath");
+    args[idx++] = os::strdup(classpath);
+    for (int i = 0; i < arg_count; i++) {
+      if (vm_args[i] != nullptr && strstr(vm_args[i], "AutoSharedArchivePath") == nullptr
+                                && strstr(vm_args[i], "JProfilingCacheAutoArchiveDir") == nullptr) {
+        args[idx++] = os::strdup(vm_args[i]);
+      }
+    }
+    args[idx++] = os::strdup("-version");
+    args[idx] = nullptr;
+
+    if (PrintAutoAppCDS) {
+      int i = 0;
+      while (args[i] != nullptr) {
+        tty->print_cr("args[%d] = %s", i, args[i]);
+        i++;
+      }
+    }
+    execv(java_path, args);
+  }
+}
+
+void JavaThread::handle_appcds_for_executor(const JavaVMInitArgs* args) {
+  if (FLAG_IS_DEFAULT(AutoSharedArchivePath)) {
+    return;
+  }
+
+  if (AutoSharedArchivePath == nullptr) {
+    warning("AutoSharedArchivePath should not be empty. Please set the specific path.");
+    return;
+  }
+
+  static char base_path[JVM_MAXPATHLEN] = {'\0'};
+  jio_snprintf(base_path, sizeof(base_path), "%s", AutoSharedArchivePath);
+
+  struct stat st;
+  if (stat(base_path, &st) != 0) {
+    if (mkdir(base_path, 0755) != 0) {
+      vm_exit_during_initialization(err_msg("can't create dirs %s : %s", base_path, os::strerror(errno)));
+    }
+  }
+
+  char class_list_path[PATH_MAX];
+  char appcds_path[PATH_MAX];
+#if INCLUDE_AGGRESSIVE_CDS
+  char aggrecds_path[PATH_MAX];
+#endif
+
+  construct_path(class_list_path, sizeof(class_list_path), base_path, "/appcds.lst");
+  construct_path(appcds_path, sizeof(appcds_path), base_path, "/appcds.jsa");
+#if INCLUDE_AGGRESSIVE_CDS
+  construct_path(aggrecds_path, sizeof(aggrecds_path), base_path, "/aggrecds.jsa");
+#endif
+
+  if (PrintAutoAppCDS) {
+    tty->print_cr("classlist file : %s", class_list_path);
+    tty->print_cr("appcds jsa file : %s", appcds_path);
+#if INCLUDE_AGGRESSIVE_CDS
+    if (UseAggressiveCDS) {
+      tty->print_cr("aggressive jsa file : %s", aggrecds_path);
+    }
+#endif
+  }
+
+  const char* class_list_ptr = class_list_path;
+  const char* appcds_ptr = appcds_path;
+#if INCLUDE_AGGRESSIVE_CDS
+  const char* aggrecds_ptr = aggrecds_path;
+
+  if (UseAggressiveCDS) {
+    if (stat(aggrecds_path, &st) == 0) {
+      if (PrintAutoAppCDS) {
+        tty->print_cr("Use Aggressive JSA.\n");
+      }
+      UnlockDiagnosticVMOptions = true;
+      UnlockExperimentalVMOptions = true;
+      SkipSharedClassPathCheck = true;
+      UseSharedSpaces = true;
+      RequireSharedSpaces = true;
+      JVMFlagAccess::set_ccstr(JVMFlag::find_declared_flag((char*)"SharedArchiveFile"), &aggrecds_ptr, JVMFlagOrigin::COMMAND_LINE);
+      return;
+    }
+  }
+#endif
+
+  if (stat(appcds_path, &st) == 0) {
+#if INCLUDE_AGGRESSIVE_CDS
+    if (UseAggressiveCDS) {
+      if (PrintAutoAppCDS) {
+        tty->print_cr("Generate Aggressive JSA.\n");
+      }
+    }
+#endif
+    UnlockDiagnosticVMOptions = true;
+    UnlockExperimentalVMOptions = true;
+    SkipSharedClassPathCheck = true;
+    UseSharedSpaces = true;
+    RequireSharedSpaces = true;
+    JVMFlagAccess::set_ccstr(JVMFlag::find_declared_flag((char*)"SharedArchiveFile"), &appcds_ptr, JVMFlagOrigin::COMMAND_LINE);
+#if INCLUDE_AGGRESSIVE_CDS
+    if (UseAggressiveCDS) {
+      DynamicDumpSharedSpaces = true;
+      JVMFlagAccess::set_ccstr(JVMFlag::find_declared_flag((char*)"ArchiveClassesAtExit"), &aggrecds_ptr, JVMFlagOrigin::COMMAND_LINE);
+    }
+#endif
+    return;
+  }
+
+  if (stat(class_list_path, &st) == 0) {
+    if (!can_read_classlist(class_list_path)) {
+      if (PrintAutoAppCDS) {
+        tty->print_cr("classlist is generating, can't create jsa by %d now.", os::current_process_id());
+      }
+      return;
+    }
+    if (stat(appcds_path, &st) != 0) {
+      if (PrintAutoAppCDS) {
+        tty->print_cr("generate JSA file by %d.", os::current_process_id());
+      }
+      create_jsa(class_list_path, appcds_path, args);
+    }
+  } else {
+    if (!can_read_classlist(class_list_path)) {
+      return;
+    }
+    if (PrintAutoAppCDS) {
+      tty->print_cr("generate classlist file by %d.", os::current_process_id());
+    }
+    if (NUMANodesRandom != 0) {
+      NUMANodesRandom = 0;
+    }
+    UseSharedSpaces = false;
+    RequireSharedSpaces = false;
+    JVMFlagAccess::set_ccstr(JVMFlag::find_declared_flag((char*)"DumpLoadedClassList"), &class_list_ptr, JVMFlagOrigin::COMMAND_LINE);
+  }
+}
diff --git a/src/hotspot/os_cpu/linux_aarch64/javaThread_linux_aarch64.hpp b/src/hotspot/os_cpu/linux_aarch64/javaThread_linux_aarch64.hpp
index c6e012ecf..e86fa6ba8 100644
--- a/src/hotspot/os_cpu/linux_aarch64/javaThread_linux_aarch64.hpp
+++ b/src/hotspot/os_cpu/linux_aarch64/javaThread_linux_aarch64.hpp
@@ -49,4 +49,6 @@ public:
 
   static Thread *aarch64_get_thread_helper();
 
+  static void handle_appcds_for_executor(const JavaVMInitArgs* args);
+
 #endif // OS_CPU_LINUX_AARCH64_JAVATHREAD_LINUX_AARCH64_HPP
diff --git a/src/hotspot/share/cds/cdsConstants.cpp b/src/hotspot/share/cds/cdsConstants.cpp
index 6dbacb277..6c7a975a5 100644
--- a/src/hotspot/share/cds/cdsConstants.cpp
+++ b/src/hotspot/share/cds/cdsConstants.cpp
@@ -41,6 +41,9 @@ CDSConst CDSConstants::offsets[] = {
   { "FileMapHeader::_common_app_classpath_prefix_size",   offset_of(FileMapHeader, _common_app_classpath_prefix_size)   },
   { "CDSFileMapRegion::_crc",                             offset_of(CDSFileMapRegion, _crc)                             },
   { "CDSFileMapRegion::_used",                            offset_of(CDSFileMapRegion, _used)                            },
+#if INCLUDE_AGGRESSIVE_CDS
+  { "DynamicArchiveHeader::_program_crc",                 offset_of(DynamicArchiveHeader, _program_crc)                 },
+#endif // INCLUDE_AGGRESSIVE_CDS
   { "DynamicArchiveHeader::_base_region_crc",             offset_of(DynamicArchiveHeader, _base_region_crc)             }
 };
 
diff --git a/src/hotspot/share/cds/cds_globals.hpp b/src/hotspot/share/cds/cds_globals.hpp
index 546c7f1fe..be794a81f 100644
--- a/src/hotspot/share/cds/cds_globals.hpp
+++ b/src/hotspot/share/cds/cds_globals.hpp
@@ -57,7 +57,7 @@
           "Address to allocate shared memory region for class data")        \
           range(0, SIZE_MAX)                                                \
                                                                             \
-  product(ccstr, SharedArchiveConfigFile, nullptr,                             \
+  product(ccstr, SharedArchiveConfigFile, nullptr,                          \
           "Data to add to the CDS archive file")                            \
                                                                             \
   product(uint, SharedSymbolTableBucketSize, 4,                             \
@@ -67,25 +67,25 @@
   product(bool, AllowArchivingWithJavaAgent, false, DIAGNOSTIC,             \
           "Allow Java agent to be run with CDS dumping")                    \
                                                                             \
-  develop(ccstr, ArchiveHeapTestClass, nullptr,                                \
+  develop(ccstr, ArchiveHeapTestClass, nullptr,                             \
           "For JVM internal testing only. The static field named "          \
           "\"archivedObjects\" of the specified class is stored in the "    \
           "CDS archive heap")                                               \
                                                                             \
-  product(ccstr, DumpLoadedClassList, nullptr,                                 \
+  product(ccstr, DumpLoadedClassList, nullptr,                              \
           "Dump the names all loaded classes, that could be stored into "   \
           "the CDS archive, in the specified file")                         \
                                                                             \
-  product(ccstr, SharedClassListFile, nullptr,                                 \
+  product(ccstr, SharedClassListFile, nullptr,                              \
           "Override the default CDS class list")                            \
                                                                             \
-  product(ccstr, SharedArchiveFile, nullptr,                                   \
+  product(ccstr, SharedArchiveFile, nullptr,                                \
           "Override the default location of the CDS archive file")          \
                                                                             \
-  product(ccstr, ArchiveClassesAtExit, nullptr,                                \
+  product(ccstr, ArchiveClassesAtExit, nullptr,                             \
           "The path and name of the dynamic archive file")                  \
                                                                             \
-  product(ccstr, ExtraSharedClassListFile, nullptr,                            \
+  product(ccstr, ExtraSharedClassListFile, nullptr,                         \
           "Extra classlist for building the CDS archive file")              \
                                                                             \
   product(int, ArchiveRelocationMode, 1, DIAGNOSTIC,                        \
@@ -95,6 +95,20 @@
            "(2) always map at preferred address, and if unsuccessful, "     \
            "do not map the archive")                                        \
            range(0, 2)                                                      \
+                                                                            \
+  AGGRESSIVE_CDS_ONLY(product(bool, UseAggressiveCDS, false, EXPERIMENTAL,  \
+          "An aggressive stratage to improve start-up "                     \
+          "because we avoid decoding the classfile."))                      \
+                                                                            \
+  AGGRESSIVE_CDS_ONLY(product(bool, CheckClassFileTimeStamp, true, EXPERIMENTAL, \
+          "Check whether the modification time of the"                      \
+          "class file is changed during UseAggressiveCDS."))                \
+                                                                            \
+  product(bool, SkipSharedClassPathCheck, false, DIAGNOSTIC,                \
+          "Skips SharedClassPath check in DynamicCDS, which allows"         \
+          "non-empty directories to exist in classpath when DynamicDS"      \
+          "is used")                                                        \
+                                                                            \
 // end of CDS_FLAGS
 
 DECLARE_FLAGS(CDS_FLAGS)
diff --git a/src/hotspot/share/cds/dumpTimeClassInfo.cpp b/src/hotspot/share/cds/dumpTimeClassInfo.cpp
index 6ee18c17a..8ad6cfa9d 100644
--- a/src/hotspot/share/cds/dumpTimeClassInfo.cpp
+++ b/src/hotspot/share/cds/dumpTimeClassInfo.cpp
@@ -26,6 +26,7 @@
 #include "cds/archiveBuilder.hpp"
 #include "cds/dumpTimeClassInfo.inline.hpp"
 #include "cds/runTimeClassInfo.hpp"
+#include "classfile/classFileStream.hpp"
 #include "classfile/classLoader.hpp"
 #include "classfile/classLoaderData.inline.hpp"
 #include "classfile/systemDictionaryShared.hpp"
@@ -40,6 +41,10 @@ DumpTimeClassInfo::~DumpTimeClassInfo() {
   if (_loader_constraints != nullptr) {
     delete _loader_constraints;
   }
+#if INCLUDE_AGGRESSIVE_CDS
+  free_shared_class_file();
+  free_url_string();
+#endif
 }
 
 size_t DumpTimeClassInfo::runtime_info_bytesize() const {
@@ -181,3 +186,25 @@ void DumpTimeSharedClassTable::update_counts() {
   CountClassByCategory counter(this);
   iterate_all_live_classes(&counter);
 }
+
+#if INCLUDE_AGGRESSIVE_CDS
+void DumpTimeClassInfo::copy_shared_class_file(ClassFileStream* cfs) {
+  assert(_shared_class_file == nullptr, "already have _shared_class_file");
+  int stream_length = cfs->length();
+  int size = offset_of(DTSharedData, data) + stream_length;
+  _shared_class_file = (DTSharedData*) NEW_C_HEAP_ARRAY(u1, size, mtClassShared);
+  _shared_class_file->length = stream_length;
+  memcpy(_shared_class_file->data, cfs->buffer(), stream_length);
+  assert(size == _shared_class_file->obj_size(), "sanity");
+}
+
+void DumpTimeClassInfo::copy_url_string(char* string_value) {
+  assert(strlen(string_value) != 0, "sanity");
+  int string_len = strlen(string_value) + 1;
+  int size = offset_of(DTSharedData, data) + string_len;
+  _url_string = (DTSharedData*) NEW_C_HEAP_ARRAY(u1, size, mtClassShared);
+  _url_string->length = string_len;
+  memcpy(_url_string->data, string_value, string_len);
+  assert(size == _url_string->obj_size(), "sanity");
+}
+#endif // INCLUDE_AGGRESSIVE_CDS
diff --git a/src/hotspot/share/cds/dumpTimeClassInfo.hpp b/src/hotspot/share/cds/dumpTimeClassInfo.hpp
index d5ad90f35..f698b5c48 100644
--- a/src/hotspot/share/cds/dumpTimeClassInfo.hpp
+++ b/src/hotspot/share/cds/dumpTimeClassInfo.hpp
@@ -80,6 +80,14 @@ class DumpTimeClassInfo: public CHeapObj<mtClass> {
     char loader_type2() { return _loader_type2; }
   };
 
+  #if INCLUDE_AGGRESSIVE_CDS
+  struct DTSharedData {
+    int length;
+    u1 data[1];
+    int obj_size() { return sizeof(length) + length; }
+  };
+#endif // INCLUDE_AGGRESSIVE_CDS
+
   class DTVerifierConstraint {
     Symbol* _name;
     Symbol* _from_name;
@@ -128,6 +136,11 @@ public:
   GrowableArray<char>*                 _verifier_constraint_flags;
   GrowableArray<DTLoaderConstraint>*   _loader_constraints;
   GrowableArray<int>*                  _enum_klass_static_fields;
+#if INCLUDE_AGGRESSIVE_CDS
+  DTSharedData*                        _shared_class_file;
+  DTSharedData*                        _url_string;
+  int64_t                               _classfile_timestamp;
+#endif // INCLUDE_AGGRESSIVE_CDS
 
   DumpTimeClassInfo() {
     _klass = nullptr;
@@ -144,6 +157,11 @@ public:
     _verifier_constraint_flags = nullptr;
     _loader_constraints = nullptr;
     _enum_klass_static_fields = nullptr;
+#if INCLUDE_AGGRESSIVE_CDS
+    _shared_class_file = nullptr;
+    _url_string = nullptr;
+    _classfile_timestamp = 0;
+#endif // INCLUDE_AGGRESSIVE_CDS
   }
   DumpTimeClassInfo& operator=(const DumpTimeClassInfo&) = delete;
   ~DumpTimeClassInfo();
@@ -212,6 +230,56 @@ public:
   InstanceKlass* nest_host() const                  { return _nest_host; }
   void set_nest_host(InstanceKlass* nest_host)      { _nest_host = nest_host; }
 
+#if INCLUDE_AGGRESSIVE_CDS
+  DTSharedData* shared_class_file() {
+    return _shared_class_file;
+  }
+
+  int shared_class_file_size() {
+    if (_shared_class_file != nullptr) {
+      return _shared_class_file->obj_size();
+    }
+    return 0;
+  }
+
+  void copy_shared_class_file(ClassFileStream* cfs);
+
+  void free_shared_class_file() {
+    if (_shared_class_file != nullptr) {
+      FREE_C_HEAP_ARRAY(u1, _shared_class_file);
+      _shared_class_file = nullptr;
+    }
+  }
+
+  DTSharedData* url_string() {
+    return _url_string;
+  }
+
+  int url_string_size() {
+    if (_url_string != nullptr) {
+      return _url_string->obj_size();
+    }
+    return 0;
+  }
+
+  void copy_url_string(char* string_value);
+
+  void free_url_string() {
+    if (_url_string != nullptr) {
+      FREE_C_HEAP_ARRAY(u1, _url_string);
+      _url_string = nullptr;
+    }
+  }
+
+  int64_t classfile_timestamp() {
+    return _classfile_timestamp;
+  }
+
+  void set_classfile_timestamp(int64_t classfile_timestamp) {
+    _classfile_timestamp = classfile_timestamp;
+  }
+#endif // INCLUDE_AGGRESSIVE_CDS
+
   size_t runtime_info_bytesize() const;
 };
 
diff --git a/src/hotspot/share/cds/dynamicArchive.cpp b/src/hotspot/share/cds/dynamicArchive.cpp
index e2754a839..df37926da 100644
--- a/src/hotspot/share/cds/dynamicArchive.cpp
+++ b/src/hotspot/share/cds/dynamicArchive.cpp
@@ -31,6 +31,7 @@
 #include "cds/dynamicArchive.hpp"
 #include "cds/lambdaFormInvokers.hpp"
 #include "cds/metaspaceShared.hpp"
+#include "classfile/classLoader.hpp"
 #include "classfile/classLoaderData.inline.hpp"
 #include "classfile/symbolTable.hpp"
 #include "classfile/systemDictionaryShared.hpp"
@@ -51,6 +52,9 @@
 #include "utilities/align.hpp"
 #include "utilities/bitMap.inline.hpp"
 
+#ifndef O_BINARY       // if defined (Win32) use binary files.
+#define O_BINARY 0     // otherwise do nothing.
+#endif
 
 class DynamicArchiveBuilder : public ArchiveBuilder {
   const char* _archive_name;
@@ -183,6 +187,14 @@ void DynamicArchiveBuilder::init_header() {
   _header = mapinfo->dynamic_header();
 
   _header->set_base_header_crc(base_info->crc());
+#if INCLUDE_AGGRESSIVE_CDS
+  if (UseAggressiveCDS) {
+    int crc = DynamicArchiveHeader::get_current_program_crc();
+    _header->set_program_crc(crc);
+  } else {
+    _header->set_program_crc(0);
+  }
+#endif // INCLUDE_AGGRESSIVE_CDS
   for (int i = 0; i < MetaspaceShared::n_regions; i++) {
     _header->set_base_region_crc(i, base_info->region_crc(i));
   }
@@ -424,6 +436,16 @@ bool DynamicArchive::validate(FileMapInfo* dynamic_info) {
     return false;
   }
 
+#if INCLUDE_AGGRESSIVE_CDS
+  // Check the program crc
+  if (UseAggressiveCDS) {
+    if (dynamic_header->program_crc() != DynamicArchiveHeader::get_current_program_crc()) {
+      log_warning(cds)("Aggressive Dynamic archive cannot be used: program crc verification failed.");
+      return false;
+    }
+  }
+#endif // INCLUDE_AGGRESSIVE_CDS
+
   // Check each space's crc
   for (int i = 0; i < MetaspaceShared::n_regions; i++) {
     if (dynamic_header->base_region_crc(i) != base_info->region_crc(i)) {
@@ -435,10 +457,45 @@ bool DynamicArchive::validate(FileMapInfo* dynamic_info) {
   return true;
 }
 
+#if INCLUDE_AGGRESSIVE_CDS
+int DynamicArchiveHeader::get_current_program_crc() {
+  int cur_crc = 0;
+  const char* full_cmd = Arguments::java_command();
+  if (full_cmd == NULL) {
+    return 0;
+  }
+  const char* main_path = Arguments::get_appclasspath();
+  int main_path_len = strlen(main_path);
+  bool is_jar_file = strncmp(full_cmd, main_path, main_path_len) == 0;
+  if (is_jar_file) {
+    int fd = os::open(main_path, O_RDONLY | O_BINARY, 0);
+    assert(fd >= 0, "sanity");
+
+    uint32_t file_size = (uint32_t) os::lseek(fd, 0, SEEK_END);
+    os::lseek(fd, 0, SEEK_SET);
+    uint32_t max_size = 40 * 1024 * 1024; // 40M
+
+    ResourceMark rm;
+    char* buf = NEW_RESOURCE_ARRAY(char, max_size);
+
+    while(file_size) {
+      uint32_t size = MIN2(max_size, file_size);
+      size_t n = read(fd, buf, (unsigned int)size);
+      file_size -= n;
+      cur_crc = ClassLoader::crc32(cur_crc, buf, n);
+    }
+  }
+  return cur_crc;
+}
+#endif // INCLUDE_AGGRESSIVE_CDS
+
 void DynamicArchiveHeader::print(outputStream* st) {
   ResourceMark rm;
 
   st->print_cr("- base_header_crc:                0x%08x", base_header_crc());
+#if INCLUDE_AGGRESSIVE_CDS
+  st->print_cr("- program_crc:                    0x%08x", program_crc());
+#endif // INCLUDE_AGGRESSIVE_CDS
   for (int i = 0; i < NUM_CDS_REGIONS; i++) {
     st->print_cr("- base_region_crc[%d]:             0x%08x", i, base_region_crc(i));
   }
diff --git a/src/hotspot/share/cds/dynamicArchive.hpp b/src/hotspot/share/cds/dynamicArchive.hpp
index ef40d942d..7d04ba3d5 100644
--- a/src/hotspot/share/cds/dynamicArchive.hpp
+++ b/src/hotspot/share/cds/dynamicArchive.hpp
@@ -40,6 +40,9 @@ class DynamicArchiveHeader : public FileMapHeader {
   friend class CDSConstants;
 private:
   int _base_header_crc;
+#if INCLUDE_AGGRESSIVE_CDS
+  int _program_crc;
+#endif // INCLUDE_AGGRESSIVE_CDS
   int _base_region_crc[MetaspaceShared::n_regions];
 
 public:
@@ -50,6 +53,11 @@ public:
   }
 
   void set_base_header_crc(int c) { _base_header_crc = c; }
+#if INCLUDE_AGGRESSIVE_CDS
+  int program_crc() const { return _program_crc; }
+  void set_program_crc(int c) { _program_crc = c; }
+  static int get_current_program_crc();
+#endif // INCLUDE_AGGRESSIVE_CDS
   void set_base_region_crc(int i, int c) {
     assert(is_valid_region(i), "must be");
     _base_region_crc[i] = c;
diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp
index 11f05bff4..27b72f52a 100644
--- a/src/hotspot/share/cds/filemap.cpp
+++ b/src/hotspot/share/cds/filemap.cpp
@@ -193,7 +193,14 @@ void FileMapHeader::populate(FileMapInfo *info, size_t core_region_alignment,
   set_base_archive_name_offset((unsigned int)base_archive_name_offset);
   set_base_archive_name_size((unsigned int)base_archive_name_size);
   set_common_app_classpath_prefix_size((unsigned int)common_app_classpath_prefix_size);
-  set_magic(DynamicDumpSharedSpaces ? CDS_DYNAMIC_ARCHIVE_MAGIC : CDS_ARCHIVE_MAGIC);
+#if INCLUDE_AGGRESSIVE_CDS
+  if (UseAggressiveCDS && DynamicDumpSharedSpaces) {
+    set_magic(CDS_AGGRESSIVE_ARCHIVE_MAGIC);
+  } else
+#endif // INCLUDE_AGGRESSIVE_CDS
+  {
+    set_magic(DynamicDumpSharedSpaces ? CDS_DYNAMIC_ARCHIVE_MAGIC : CDS_ARCHIVE_MAGIC);
+  }
   set_version(CURRENT_CDS_ARCHIVE_VERSION);
 
   if (!info->is_static() && base_archive_name_size != 0) {
@@ -402,14 +409,16 @@ bool SharedClassPathEntry::validate(bool is_class_path) const {
   bool ok = true;
   log_info(class, path)("checking shared classpath entry: %s", name);
   if (os::stat(name, &st) != 0 && is_class_path) {
-    // If the archived module path entry does not exist at runtime, it is not fatal
-    // (no need to invalid the shared archive) because the shared runtime visibility check
-    // filters out any archived module classes that do not have a matching runtime
-    // module path location.
-    log_warning(cds)("Required classpath entry does not exist: %s", name);
-    ok = false;
+    if (!SkipSharedClassPathCheck) {
+      // If the archived module path entry does not exist at runtime, it is not fatal
+      // (no need to invalid the shared archive) because the shared runtime visibility check
+      // filters out any archived module classes that do not have a matching runtime
+      // module path location.
+      log_warning(cds)("Required classpath entry does not exist: %s", name);
+      ok = false;
+    }
   } else if (is_dir()) {
-    if (!os::dir_is_empty(name)) {
+    if (!SkipSharedClassPathCheck && !os::dir_is_empty(name)) {
       log_warning(cds)("directory is not empty: %s", name);
       ok = false;
     }
@@ -528,6 +537,10 @@ int FileMapInfo::add_shared_classpaths(int i, const char* which, ClassPathEntry
 }
 
 void FileMapInfo::check_nonempty_dir_in_shared_path_table() {
+  if (SkipSharedClassPathCheck) {
+    return;
+  }
+
   Arguments::assert_is_dumping_archive();
 
   bool has_nonempty_dir = false;
@@ -592,7 +605,7 @@ int FileMapInfo::get_module_shared_path_index(Symbol* location) {
   const char* file = ClassLoader::uri_to_path(location->as_C_string());
   for (int i = ClassLoaderExt::app_module_paths_start_index(); i < get_number_of_shared_paths(); i++) {
     SharedClassPathEntry* ent = shared_path(i);
-    assert(ent->in_named_module(), "must be");
+    assert(ent->in_named_module() || SkipSharedClassPathCheck, "must be");
     bool cond = strcmp(file, ent->name()) == 0;
     log_debug(class, path)("get_module_shared_path_index (%d) %s : %s = %s", i,
                            location->as_C_string(), ent->name(), cond ? "same" : "different");
@@ -863,6 +876,9 @@ bool FileMapInfo::validate_boot_class_paths() {
 }
 
 bool FileMapInfo::validate_app_class_paths(int shared_app_paths_len) {
+  if (SkipSharedClassPathCheck) {
+    return true;
+  }
   const char *appcp = Arguments::get_appclasspath();
   assert(appcp != nullptr, "null app classpath");
   int rp_len = num_paths(appcp);
@@ -1118,7 +1134,8 @@ public:
     }
 
     if (gen_header._magic != CDS_ARCHIVE_MAGIC &&
-        gen_header._magic != CDS_DYNAMIC_ARCHIVE_MAGIC) {
+        gen_header._magic != CDS_DYNAMIC_ARCHIVE_MAGIC
+        AGGRESSIVE_CDS_ONLY(&& gen_header._magic != CDS_AGGRESSIVE_ARCHIVE_MAGIC)) {
       log_warning(cds)("The shared archive file has a bad magic number: %#x", gen_header._magic);
       return false;
     }
@@ -1208,7 +1225,8 @@ public:
         return false;
       }
     } else {
-      assert(_header->_magic == CDS_DYNAMIC_ARCHIVE_MAGIC, "must be");
+      assert(_header->_magic == CDS_DYNAMIC_ARCHIVE_MAGIC
+             AGGRESSIVE_CDS_ONLY(|| _header->_magic == CDS_AGGRESSIVE_ARCHIVE_MAGIC), "must be");
       if ((name_size == 0 && name_offset != 0) ||
           (name_size != 0 && name_offset == 0)) {
         // If either is zero, both must be zero. This indicates that we are using the default base archive.
@@ -1256,7 +1274,8 @@ bool FileMapInfo::get_base_archive_name_from_header(const char* archive_name,
     return false;
   }
   GenericCDSFileMapHeader* header = file_helper.get_generic_file_header();
-  if (header->_magic != CDS_DYNAMIC_ARCHIVE_MAGIC) {
+  if (header->_magic != CDS_DYNAMIC_ARCHIVE_MAGIC
+      AGGRESSIVE_CDS_ONLY(&& header->_magic != CDS_AGGRESSIVE_ARCHIVE_MAGIC)) {
     assert(header->_magic == CDS_ARCHIVE_MAGIC, "must be");
     if (AutoCreateSharedArchive) {
      log_warning(cds)("AutoCreateSharedArchive is ignored because %s is a static archive", archive_name);
@@ -1290,7 +1309,8 @@ bool FileMapInfo::init_from_file(int fd) {
       return false;
     }
   } else {
-    if (gen_header->_magic != CDS_DYNAMIC_ARCHIVE_MAGIC) {
+    if (gen_header->_magic != CDS_DYNAMIC_ARCHIVE_MAGIC
+        AGGRESSIVE_CDS_ONLY(&& gen_header->_magic != CDS_AGGRESSIVE_ARCHIVE_MAGIC)) {
       log_warning(cds)("Not a top shared archive: %s", _full_path);
       return false;
     }
@@ -2467,7 +2487,7 @@ ClassPathEntry* FileMapInfo::get_classpath_entry_for_jvmti(int i, TRAPS) {
   ClassPathEntry* ent = _classpath_entries_for_jvmti[i];
   if (ent == nullptr) {
     SharedClassPathEntry* scpe = shared_path(i);
-    assert(scpe->is_jar(), "must be"); // other types of scpe will not produce archived classes
+    assert(scpe->is_jar() || SkipSharedClassPathCheck, "must be"); // other types of scpe will not produce archived classes
 
     const char* path = scpe->name();
     struct stat st;
diff --git a/src/hotspot/share/cds/metaspaceShared.cpp b/src/hotspot/share/cds/metaspaceShared.cpp
index 86be63c7b..137112558 100644
--- a/src/hotspot/share/cds/metaspaceShared.cpp
+++ b/src/hotspot/share/cds/metaspaceShared.cpp
@@ -577,7 +577,7 @@ bool MetaspaceShared::may_be_eagerly_linked(InstanceKlass* ik) {
     // linked/verified at runtime.
     return false;
   }
-  if (DynamicDumpSharedSpaces && ik->is_shared_unregistered_class()) {
+  if (DynamicDumpSharedSpaces && ik->is_shared_unregistered_class() AGGRESSIVE_CDS_ONLY(&& !UseAggressiveCDS)) {
     // Linking of unregistered classes at this stage may cause more
     // classes to be resolved, resulting in calls to ClassLoader.loadClass()
     // that may not be expected by custom class loaders.
diff --git a/src/hotspot/share/cds/runTimeClassInfo.cpp b/src/hotspot/share/cds/runTimeClassInfo.cpp
index 2536b5330..c1298e388 100644
--- a/src/hotspot/share/cds/runTimeClassInfo.cpp
+++ b/src/hotspot/share/cds/runTimeClassInfo.cpp
@@ -26,7 +26,19 @@
 #include "cds/archiveBuilder.hpp"
 #include "cds/dumpTimeClassInfo.hpp"
 #include "cds/runTimeClassInfo.hpp"
+#include "classfile/classFileStream.hpp"
+#include "classfile/javaClasses.hpp"
+#include "classfile/javaClasses.inline.hpp"
 #include "classfile/systemDictionaryShared.hpp"
+#include "classfile/vmSymbols.hpp"
+#include "logging/log.hpp"
+#include "logging/logStream.hpp"
+#include "runtime/handles.inline.hpp"
+#include "runtime/javaCalls.hpp"
+#include "oops/oop.inline.hpp"
+#if INCLUDE_AGGRESSIVE_CDS
+#include "runtime/os.hpp"
+#endif
 
 void RunTimeClassInfo::init(DumpTimeClassInfo& info) {
   ArchiveBuilder* builder = ArchiveBuilder::current();
@@ -72,6 +84,27 @@ void RunTimeClassInfo::init(DumpTimeClassInfo& info) {
       set_enum_klass_static_field_root_index_at(i, root_index);
     }
   }
+
+#if INCLUDE_AGGRESSIVE_CDS
+  if (info.shared_class_file_size() != 0) {
+    assert(_url_string == nullptr, "must assigned before _url_string");
+    _shared_class_file = shared_class_file();
+    memcpy(_shared_class_file, info.shared_class_file(), info.shared_class_file_size());
+    ArchivePtrMarker::mark_pointer(&_shared_class_file);
+    info.free_shared_class_file();
+  } else {
+    _shared_class_file = nullptr;
+  }
+  if (info.url_string_size() != 0) {
+    _url_string = url_string();
+    memcpy(_url_string, info.url_string(), info.url_string_size());
+    ArchivePtrMarker::mark_pointer(&_url_string);
+    info.free_url_string();
+  } else {
+    _url_string = nullptr;
+  }
+  set_classfile_timestamp(info.classfile_timestamp());
+#endif // INCLUDE_AGGRESSIVE_CDS
 }
 
 size_t RunTimeClassInfo::crc_size(InstanceKlass* klass) {
@@ -81,3 +114,79 @@ size_t RunTimeClassInfo::crc_size(InstanceKlass* klass) {
     return 0;
   }
 }
+
+#if INCLUDE_AGGRESSIVE_CDS
+// check timestamp in the load time when UseAggressiveCDS.
+//   regular_file(*.class): need to check timestamp.
+//   jar_file(*.jar): no need to check timestamp here, already checked
+//                    somewhere else, see SharedClassPathEntry::validate.
+//   other_file: not supported when UseAggressiveCDS.
+bool RunTimeClassInfo::check_classfile_timestamp(char* url_string, TRAPS) {
+  if (SystemDictionaryShared::is_regular_file(url_string)) {
+    ResourceMark rm(THREAD);
+    char* dir = SystemDictionaryShared::get_filedir(url_string);
+    if (dir == nullptr) {
+      return false;
+    }
+    int64_t timestamp = SystemDictionaryShared::get_timestamp(dir, _klass->name());
+    if (timestamp != _classfile_timestamp) {
+      log_trace(cds, aggressive)("%s, timestamp mismatch: " INT64_FORMAT " -> " INT64_FORMAT,
+                                  _klass->name()->as_C_string(),
+                                  _classfile_timestamp, timestamp);
+      return false;
+    }
+  } else if (!SystemDictionaryShared::is_jar_file(url_string)) {
+    log_trace(cds, aggressive)("Unsupported URL:%s", url_string);
+    return false;
+  }
+  return true;
+}
+
+Handle RunTimeClassInfo::get_protection_domain(Handle class_loader, TRAPS) {
+  if (_url_string == nullptr) {
+    return Handle();
+  }
+  char* data_ptr = (char*)(_url_string->data);
+
+  if (CheckClassFileTimeStamp) {
+    if (!check_classfile_timestamp(data_ptr, THREAD)) {
+      return Handle();
+    }
+  }
+
+  Handle url_string = java_lang_String::create_from_str(data_ptr, THREAD);
+  JavaValue result(T_OBJECT);
+  JavaCalls::call_virtual(&result,
+                          class_loader,
+                          class_loader->klass(),
+                          vmSymbols::getProtectionDomainByURLString_name(),
+                          vmSymbols::getProtectionDomainByURLString_signature(),
+                          url_string, THREAD);
+  if (!HAS_PENDING_EXCEPTION) {
+    return Handle(THREAD, result.get_oop());
+  } else {
+    LogTarget(Warning, cds, aggressive) lt;
+    if (lt.is_enabled()) {
+      lt.print("Unknown exception in get_protection_domain():");
+      ResourceMark rm(THREAD);
+      Handle ex(THREAD, THREAD->pending_exception());
+      CLEAR_PENDING_EXCEPTION;
+      LogStream ls(lt);
+      java_lang_Throwable::print_stack_trace(ex, &ls);
+    } else {
+      CLEAR_PENDING_EXCEPTION;
+    }
+  }
+  return Handle();
+}
+
+ClassFileStream* RunTimeClassInfo::get_shared_class_file_stream() {
+  if (_shared_class_file != nullptr) {
+    return new ClassFileStream(_shared_class_file->data,
+                               _shared_class_file->length,
+                               "__VM_AggressiveCDS__",
+                               ClassFileStream::verify);
+  }
+  return nullptr;
+}
+#endif // INCLUDE_AGGRESSIVE_CDS
diff --git a/src/hotspot/share/cds/runTimeClassInfo.hpp b/src/hotspot/share/cds/runTimeClassInfo.hpp
index b5ffe0028..d1a171bdc 100644
--- a/src/hotspot/share/cds/runTimeClassInfo.hpp
+++ b/src/hotspot/share/cds/runTimeClassInfo.hpp
@@ -69,7 +69,20 @@ public:
     int _root_indices[1];
   };
 
+#if INCLUDE_AGGRESSIVE_CDS
+  struct RTSharedData {
+    int length;
+    u1 data[1];
+    int obj_size() { return sizeof(length) + length; }
+  };
+#endif // INCLUDE_AGGRESSIVE_CDS
+
   InstanceKlass* _klass;
+#if INCLUDE_AGGRESSIVE_CDS
+  RTSharedData* _shared_class_file;
+  RTSharedData* _url_string;
+  int64_t       _classfile_timestamp;
+#endif // INCLUDE_AGGRESSIVE_CDS
   int _num_verifier_constraints;
   int _num_loader_constraints;
 
@@ -106,6 +119,12 @@ private:
     }
   }
 
+#if INCLUDE_AGGRESSIVE_CDS
+  static size_t shared_class_file_size(DumpTimeClassInfo& info) {
+    return info.shared_class_file_size();
+  }
+#endif // INCLUDE_AGGRESSIVE_CDS
+
   static size_t crc_size(InstanceKlass* klass);
 public:
   static size_t byte_size(InstanceKlass* klass, int num_verifier_constraints, int num_loader_constraints,
@@ -119,6 +138,24 @@ public:
            enum_klass_static_fields_size(num_enum_klass_static_fields);
   }
 
+#if INCLUDE_AGGRESSIVE_CDS
+  static size_t byte_size(DumpTimeClassInfo& info) {
+    size_t previous_size = byte_size(info._klass, info.num_verifier_constraints(), info.num_loader_constraints(),
+                                     info.num_enum_klass_static_fields());
+    if (UseAggressiveCDS) {
+      size_t cf_size = shared_class_file_size(info);
+      if (cf_size != 0) {
+        previous_size = align_up(previous_size, sizeof(int)) + cf_size;
+      }
+      cf_size = info.url_string_size();
+      if (cf_size != 0) {
+        return align_up(previous_size, sizeof(int)) + cf_size;
+      }
+    }
+    return previous_size;
+  }
+#endif // INCLUDE_AGGRESSIVE_CDS
+
 private:
   size_t crc_offset() const {
     return header_size_size();
@@ -141,6 +178,19 @@ private:
     return verifier_constraint_flags_offset() + verifier_constraint_flags_size(_num_verifier_constraints);
   }
 
+#if INCLUDE_AGGRESSIVE_CDS
+  size_t shared_class_file_offset() const {
+    return align_up(enum_klass_static_fields_offset(), sizeof(int));
+  }
+  size_t url_string_offset() const {
+    size_t offset = shared_class_file_offset();
+    if (_shared_class_file != nullptr) {
+      return align_up(offset + _shared_class_file->obj_size(), sizeof(int));
+    }
+    return offset;
+  }
+#endif // INCLUDE_AGGRESSIVE_CDS
+
   void check_verifier_constraint_offset(int i) const {
     assert(0 <= i && i < _num_verifier_constraints, "sanity");
   }
@@ -191,6 +241,28 @@ public:
     return loader_constraints() + i;
   }
 
+#if INCLUDE_AGGRESSIVE_CDS
+  RTSharedData* shared_class_file() {
+    return (RTSharedData*)(address(this) + shared_class_file_offset());
+  }
+  RTSharedData* url_string() {
+    return (RTSharedData*)(address(this) + url_string_offset());
+  }
+
+  int64_t classfile_timestamp() {
+    return _classfile_timestamp;
+  }
+
+  void set_classfile_timestamp(int64_t classfile_timestamp) {
+    _classfile_timestamp = classfile_timestamp;
+  }
+
+  ClassFileStream* get_shared_class_file_stream();
+
+  bool check_classfile_timestamp(char* url_string, TRAPS);
+  Handle get_protection_domain(Handle class_loader, TRAPS);
+#endif // INCLUDE_AGGRESSIVE_CDS
+
   void init(DumpTimeClassInfo& info);
 
   bool matches(int clsfile_size, int clsfile_crc32) const {
diff --git a/src/hotspot/share/classfile/classLoader.cpp b/src/hotspot/share/classfile/classLoader.cpp
index d3a2082e8..e4d121690 100644
--- a/src/hotspot/share/classfile/classLoader.cpp
+++ b/src/hotspot/share/classfile/classLoader.cpp
@@ -1351,7 +1351,7 @@ void ClassLoader::record_result(JavaThread* current, InstanceKlass* ik,
                 (i < ClassLoaderExt::app_class_paths_start_index())) {
               // The class must be from boot loader append path which consists of
               // -Xbootclasspath/a and jvmti appended entries.
-              assert(loader == nullptr, "sanity");
+              assert(loader == nullptr || SkipSharedClassPathCheck, "sanity");
               classpath_index = i;
               break;
             }
diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp
index bae1fc9e7..da6156d6a 100644
--- a/src/hotspot/share/classfile/javaClasses.cpp
+++ b/src/hotspot/share/classfile/javaClasses.cpp
@@ -5219,6 +5219,44 @@ void java_lang_InternalError::serialize_offsets(SerializeClosure* f) {
 }
 #endif
 
+#if INCLUDE_AGGRESSIVE_CDS
+int java_security_ProtectionDomain::_code_source_offset;
+
+oop java_security_ProtectionDomain::codeSource(oop protection_domain) {
+  return protection_domain->obj_field(_code_source_offset);
+}
+
+#define PROTECTIONDOMAIN_FIELDS_DO(macro) \
+  macro(_code_source_offset, k, "codesource", codesource_signature, false)
+
+void java_security_ProtectionDomain::compute_offsets() {
+  InstanceKlass* k = vmClasses::ProtectionDomain_klass();
+  PROTECTIONDOMAIN_FIELDS_DO(FIELD_COMPUTE_OFFSET);
+}
+
+void java_security_ProtectionDomain::serialize_offsets(SerializeClosure* f) {
+  PROTECTIONDOMAIN_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
+}
+
+int java_security_CodeSource::_locationNoFragString_offset;
+
+oop java_security_CodeSource::locationNoFragString(oop code_source) {
+  return code_source->obj_field(_locationNoFragString_offset);
+}
+
+#define CODESOURCE_FIELDS_DO(macro) \
+  macro(_locationNoFragString_offset, k, "locationNoFragString", string_signature, false)
+
+void java_security_CodeSource::compute_offsets() {
+  InstanceKlass* k = vmClasses::CodeSource_klass();
+  CODESOURCE_FIELDS_DO(FIELD_COMPUTE_OFFSET);
+}
+
+void java_security_CodeSource::serialize_offsets(SerializeClosure* f) {
+  CODESOURCE_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
+}
+#endif // INCLUDE_AGGRESSIVE_CDS
+
 #define BASIC_JAVA_CLASSES_DO_PART1(f) \
   f(java_lang_Class) \
   f(java_lang_String) \
@@ -5269,6 +5307,8 @@ void java_lang_InternalError::serialize_offsets(SerializeClosure* f) {
   f(jdk_internal_misc_UnsafeConstants) \
   f(java_lang_boxing_object) \
   f(vector_VectorPayload) \
+  AGGRESSIVE_CDS_ONLY(f(java_security_ProtectionDomain)) \
+  AGGRESSIVE_CDS_ONLY(f(java_security_CodeSource)) \
   //end
 
 #define BASIC_JAVA_CLASSES_DO(f) \
diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp
index b25429d98..5c5578cce 100644
--- a/src/hotspot/share/classfile/javaClasses.hpp
+++ b/src/hotspot/share/classfile/javaClasses.hpp
@@ -1840,6 +1840,32 @@ class java_lang_InternalError : AllStatic {
   static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
 };
 
+#if INCLUDE_AGGRESSIVE_CDS
+class java_security_ProtectionDomain : AllStatic {
+ private:
+  static int _code_source_offset;
+
+ public:
+  static void compute_offsets();
+
+  static void serialize_offsets(SerializeClosure* f);
+
+  static oop  codeSource(oop protection_domain);
+};
+
+class java_security_CodeSource : AllStatic {
+ private:
+  static int _locationNoFragString_offset;
+
+ public:
+  static void compute_offsets();
+
+  static void serialize_offsets(SerializeClosure* f);
+
+  static oop locationNoFragString(oop code_source);
+};
+#endif // INCLUDE_AGGRESSIVE_CDS
+
 // Use to declare fields that need to be injected into Java classes
 // for the JVM to use.  The name_index and signature_index are
 // declared in vmSymbols.  The may_be_java flag is used to declare
diff --git a/src/hotspot/share/classfile/klassFactory.cpp b/src/hotspot/share/classfile/klassFactory.cpp
index d43364506..a68c998a4 100644
--- a/src/hotspot/share/classfile/klassFactory.cpp
+++ b/src/hotspot/share/classfile/klassFactory.cpp
@@ -40,6 +40,9 @@
 #if INCLUDE_JFR
 #include "jfr/support/jfrKlassExtension.hpp"
 #endif
+#if INCLUDE_AGGRESSIVE_CDS
+#include "classfile/systemDictionaryShared.hpp"
+#endif // INCLUDE_AGGRESSIVE_CDS
 
 
 // called during initial loading of a shared class
@@ -58,7 +61,18 @@ InstanceKlass* KlassFactory::check_shared_class_file_load_hook(
     // Post the CFLH
     JvmtiCachedClassFileData* cached_class_file = nullptr;
     if (cfs == nullptr) {
-      cfs = FileMapInfo::open_stream_for_jvmti(ik, class_loader, CHECK_NULL);
+#if INCLUDE_AGGRESSIVE_CDS
+      if (UseAggressiveCDS && !SystemDictionaryShared::is_builtin(ik)) {
+        assert(UseAggressiveCDS, "sanity check");
+        cfs = SystemDictionaryShared::get_shared_class_file_stream(ik);
+        if (cfs == nullptr) {
+          cfs = SystemDictionaryShared::get_byte_code_from_cache(class_name, class_loader, CHECK_NULL);
+        }
+      } else
+#endif // INCLUDE_AGGRESSIVE_CDS
+      {
+        cfs = FileMapInfo::open_stream_for_jvmti(ik, class_loader, CHECK_NULL);
+      }
     }
     unsigned char* ptr = (unsigned char*)cfs->buffer();
     unsigned char* end_ptr = ptr + cfs->length();
@@ -69,7 +83,7 @@ InstanceKlass* KlassFactory::check_shared_class_file_load_hook(
                                            &ptr,
                                            &end_ptr,
                                            &cached_class_file);
-    if (old_ptr != ptr) {
+    if (old_ptr != ptr AGGRESSIVE_CDS_ONLY(|| (UseAggressiveCDS && !SystemDictionaryShared::is_builtin(ik)))) {
       // JVMTI agent has modified class file data.
       // Set new class file stream using JVMTI agent modified class file data.
       ClassLoaderData* loader_data =
@@ -79,6 +93,19 @@ InstanceKlass* KlassFactory::check_shared_class_file_load_hook(
                                                     end_ptr - ptr,
                                                     cfs->source(),
                                                     ClassFileStream::verify);
+#if INCLUDE_AGGRESSIVE_CDS
+      if (UseAggressiveCDS) {
+        int stream_size  = stream->length();
+        int stream_crc32 = ClassLoader::crc32(0, (const char*)stream->buffer(), stream->length());
+        uint64_t fingerprint = (uint64_t(stream_size) << 32) | uint64_t(uint32_t(stream_crc32));
+        if (ik->get_stored_fingerprint() == fingerprint) {
+          if (cached_class_file != nullptr) {
+            ik->set_cached_class_file(cached_class_file);
+          }
+          return nullptr;
+        }
+      }
+#endif // INCLUDE_AGGRESSIVE_CDS
       ClassLoadInfo cl_info(protection_domain);
       ClassFileParser parser(stream,
                              class_name,
@@ -214,6 +241,28 @@ InstanceKlass* KlassFactory::create_from_stream(ClassFileStream* stream,
 #if INCLUDE_CDS
   if (Arguments::is_dumping_archive()) {
     ClassLoader::record_result(THREAD, result, stream, old_stream != stream);
+#if INCLUDE_AGGRESSIVE_CDS
+    if (UseAggressiveCDS && !loader_data->is_builtin_class_loader_data()) {
+      bool changed_by_loadhook = old_stream != stream;
+      if (changed_by_loadhook && !cl_info.is_hidden()) {
+        SystemDictionaryShared::set_shared_class_file(result, old_stream);
+      }
+      Handle protection_domain = cl_info.protection_domain();
+      if (protection_domain.not_null()) {
+        Handle codesource(THREAD, java_security_ProtectionDomain::codeSource(protection_domain()));
+        if (codesource.not_null()) {
+          Handle str(THREAD, java_security_CodeSource::locationNoFragString(codesource()));
+          if (str.not_null()) {
+            char* string_value = java_lang_String::as_utf8_string(str());
+            if (strlen(string_value) != 0) {
+              SystemDictionaryShared::set_url_string(result, string_value);
+              SystemDictionaryShared::save_timestamp(result, string_value);
+            }
+          }
+        }
+      }
+    }
+#endif // INCLUDE_AGGRESSIVE_CDS
   }
 #endif // INCLUDE_CDS
 
diff --git a/src/hotspot/share/classfile/systemDictionaryShared.cpp b/src/hotspot/share/classfile/systemDictionaryShared.cpp
index b7b09dc69..a0ff5d677 100644
--- a/src/hotspot/share/classfile/systemDictionaryShared.cpp
+++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp
@@ -71,6 +71,9 @@
 #include "runtime/java.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/mutexLocker.hpp"
+#if INCLUDE_AGGRESSIVE_CDS
+#include "runtime/os.hpp"
+#endif
 #include "utilities/resourceHash.hpp"
 #include "utilities/stringUtils.hpp"
 
@@ -1067,7 +1070,11 @@ public:
 
   void do_entry(InstanceKlass* k, DumpTimeClassInfo& info) {
     if (!info.is_excluded()) {
+#if INCLUDE_AGGRESSIVE_CDS
+      size_t byte_size = RunTimeClassInfo::byte_size(info);
+#else
       size_t byte_size = info.runtime_info_bytesize();
+#endif
       _shared_class_info_size += align_up(byte_size, SharedSpaceObjectAlignment);
     }
   }
@@ -1114,6 +1121,15 @@ public:
   CopyLambdaProxyClassInfoToArchive(CompactHashtableWriter* writer)
   : _writer(writer), _builder(ArchiveBuilder::current()) {}
   bool do_entry(LambdaProxyClassKey& key, DumpTimeLambdaProxyClassInfo& info) {
+#if INCLUDE_AGGRESSIVE_CDS
+    // In Dynamic dump, info is from _dumptime_lambda_proxy_class_dictionary, which is created by
+    // runtime JNI call, see Java_java_lang_invoke_LambdaProxyClassArchive_addToArchive.
+    // check_excluded_classes can't exclude DumpTimeLambdaProxyClassInfo, check excluded here
+    if (UseAggressiveCDS && DynamicDumpSharedSpaces
+        && SystemDictionaryShared::is_excluded_class(info._proxy_klasses->at(0))) {
+      return true;
+    }
+#endif // INCLUDE_AGGRESSIVE_CDS
     // In static dump, info._proxy_klasses->at(0) is already relocated to point to the archived class
     // (not the original class).
     //
@@ -1140,6 +1156,12 @@ class AdjustLambdaProxyClassInfo : StackObj {
 public:
   AdjustLambdaProxyClassInfo() {}
   bool do_entry(LambdaProxyClassKey& key, DumpTimeLambdaProxyClassInfo& info) {
+#if INCLUDE_AGGRESSIVE_CDS
+    if (UseAggressiveCDS && DynamicDumpSharedSpaces
+        && SystemDictionaryShared::is_excluded_class(info._proxy_klasses->at(0))) {
+      return true;
+    }
+#endif // INCLUDE_AGGRESSIVE_CDS
     int len = info._proxy_klasses->length();
     InstanceKlass* last_buff_k = nullptr;
 
@@ -1159,6 +1181,39 @@ public:
   }
 };
 
+#if INCLUDE_AGGRESSIVE_CDS
+class ExcludeDuplicateKlass : StackObj {
+public:
+  static const int INITIAL_TABLE_SIZE = 15889;
+
+  ExcludeDuplicateKlass() : _has_been_visited() {}
+
+  bool do_entry(InstanceKlass* k, DumpTimeClassInfo& info) {
+    if (!info.is_excluded()) {
+      bool created;
+      Symbol* name = info._klass->name();
+      address* info_ptr = _has_been_visited.put_if_absent((address)name, (address)&info, &created);
+      if (!created) {
+        info.set_excluded();
+        DumpTimeClassInfo* first_info = (DumpTimeClassInfo*)(*info_ptr);
+        if (!first_info->is_excluded()) {
+          first_info->set_excluded();
+        }
+        LogTarget(Trace, cds, aggressive) lt;
+        if (lt.is_enabled()) {
+          ResourceMark rm;
+          lt.print("Skipping duplicate class (excluded): %s", name->as_C_string());
+        }
+      }
+    }
+    return true;
+  }
+
+private:
+  ResourceHashtable<address, address, INITIAL_TABLE_SIZE, AnyObj::C_HEAP, mtClassShared> _has_been_visited;
+};
+#endif // INCLUDE_AGGRESSIVE_CDS
+
 class CopySharedClassInfoToArchive : StackObj {
   CompactHashtableWriter* _writer;
   bool _is_builtin;
@@ -1170,7 +1225,11 @@ public:
 
   void do_entry(InstanceKlass* k, DumpTimeClassInfo& info) {
     if (!info.is_excluded() && info.is_builtin() == _is_builtin) {
+#if INCLUDE_AGGRESSIVE_CDS
+      size_t byte_size = RunTimeClassInfo::byte_size(info);
+#else
       size_t byte_size = info.runtime_info_bytesize();
+#endif
       RunTimeClassInfo* record;
       record = (RunTimeClassInfo*)ArchiveBuilder::ro_region_alloc(byte_size);
       record->init(info);
@@ -1210,6 +1269,12 @@ void SystemDictionaryShared::write_dictionary(RunTimeSharedDictionary* dictionar
                                               bool is_builtin) {
   CompactHashtableStats stats;
   dictionary->reset();
+#if INCLUDE_AGGRESSIVE_CDS
+  if (UseAggressiveCDS && !is_builtin) {
+    ExcludeDuplicateKlass dup;
+    _dumptime_table->iterate_all_live_classes(&dup);
+  }
+#endif // INCLUDE_AGGRESSIVE_CDS
   CompactHashtableWriter writer(_dumptime_table->count_of(is_builtin), &stats);
   CopySharedClassInfoToArchive copy(&writer, is_builtin);
   assert_lock_strong(DumpTimeTable_lock);
@@ -1443,3 +1508,201 @@ void SystemDictionaryShared::cleanup_lambda_proxy_class_dictionary() {
   CleanupDumpTimeLambdaProxyClassTable cleanup_proxy_classes;
   _dumptime_lambda_proxy_class_dictionary->unlink(&cleanup_proxy_classes);
 }
+
+#if INCLUDE_AGGRESSIVE_CDS
+ClassFileStream* SystemDictionaryShared::get_shared_class_file_stream(InstanceKlass* k) {
+  assert(UseAggressiveCDS, "sanity");
+  RunTimeClassInfo* info = RunTimeClassInfo::get_for(k);
+  return info->get_shared_class_file_stream();
+}
+
+ClassFileStream* SystemDictionaryShared::get_byte_code_from_cache(Symbol* class_name, Handle class_loader, TRAPS) {
+  assert(UseAggressiveCDS, "sanity");
+
+  TempNewSymbol plugin_name = SymbolTable::new_symbol("java/net/AggressiveCDSPlugin");
+  InstanceKlass* plugin_klass = SystemDictionary::find_instance_klass(THREAD, plugin_name, Handle(), Handle());
+  assert(plugin_klass != nullptr, "sanity");
+  JavaValue result(T_OBJECT);
+  Handle name = java_lang_String::create_from_symbol(class_name, CHECK_NULL);
+  TempNewSymbol method_name = SymbolTable::new_symbol("getByteCodeFromCache");
+  TempNewSymbol method_signature = SymbolTable::new_symbol("(Ljava/net/URLClassLoader;Ljava/lang/String;)[B");
+
+  JavaCalls::call_static(&result,
+                         plugin_klass,
+                         method_name,
+                         method_signature,
+                         class_loader,
+                         name,
+                         CHECK_NULL);
+
+  typeArrayHandle res_h(THREAD, (typeArrayOop) result.get_oop());
+  if (res_h.is_null()) {
+    return nullptr;
+  }
+  int len = res_h->length();
+  u1* buf = NEW_RESOURCE_ARRAY(u1, len);
+  memcpy(buf, (u1*) res_h->byte_at_addr(0), len);
+  return new ClassFileStream(buf, len, "__VM_AggressiveCDS__", ClassFileStream::verify);
+}
+
+void SystemDictionaryShared::set_shared_class_file(InstanceKlass* k, ClassFileStream* cfs) {
+  assert(UseAggressiveCDS, "sanity");
+  Arguments::assert_is_dumping_archive();
+  DumpTimeClassInfo* info = get_info_locked(k);
+  if (info != nullptr && info->_shared_class_file == nullptr) {
+    info->copy_shared_class_file(cfs);
+  }
+}
+
+static const char* JAR_FILE_PREFIX = "jar://";
+static const char* FILE_SEPARATOR = "file://";
+static const char* CLASSFILE_SUFFIX = ".class";
+
+static bool start_with(char* str, const char* prefix) {
+  if (str == nullptr || prefix == nullptr || strlen(str) < strlen(prefix)) {
+    return false;
+  }
+  if (strncmp(str, prefix, strlen(prefix)) == 0) {
+    return true;
+  }
+  return false;
+}
+
+bool SystemDictionaryShared::is_jar_file(char* url_string) {
+  if (start_with(url_string, JAR_FILE_PREFIX)) {
+    return true;
+  }
+  return false;
+}
+
+bool SystemDictionaryShared::is_regular_file(char* url_string) {
+  if (start_with(url_string, FILE_SEPARATOR)) {
+    return true;
+  }
+  return false;
+}
+
+char* SystemDictionaryShared::get_filedir(char* url_string) {
+  if (!is_regular_file(url_string)) {
+    return nullptr;
+  }
+  char* dir = url_string + strlen(FILE_SEPARATOR);
+  struct stat st;
+  if (os::stat(dir, &st) == 0) {
+    if ((st.st_mode & S_IFDIR) == S_IFDIR) {
+      return dir;
+    }
+  }
+  return nullptr;
+}
+
+int64_t SystemDictionaryShared::get_timestamp(char* dir, Symbol* class_name) {
+  char* name = class_name->as_C_string();
+  size_t name_len = strlen(name);
+  size_t dir_len = strlen(dir);
+  size_t classfile_suffix_len = strlen(CLASSFILE_SUFFIX);
+  char* file_path = NEW_RESOURCE_ARRAY(char, dir_len + name_len + classfile_suffix_len + 1);
+  memcpy(file_path, dir, dir_len);
+  memcpy(file_path + dir_len, name, name_len);
+  memcpy(file_path + dir_len + name_len, CLASSFILE_SUFFIX, classfile_suffix_len + 1);
+  assert(strlen(file_path) == dir_len + name_len + classfile_suffix_len, "sanity");
+  struct stat st;
+  if (os::stat(file_path, &st) == 0) {
+    return st.st_mtime;
+  }
+  log_trace(cds, aggressive)("get timestamp failed:%s", file_path);
+  return 0;
+}
+
+Handle SystemDictionaryShared::get_protection_domain(InstanceKlass* k, Handle class_loader, TRAPS) {
+  assert(UseAggressiveCDS, "sanity");
+  RunTimeClassInfo* info = RunTimeClassInfo::get_for(k);
+  return info->get_protection_domain(class_loader, CHECK_NH);
+}
+
+void SystemDictionaryShared::set_url_string(InstanceKlass* k, char* string_value) {
+  assert(UseAggressiveCDS, "sanity");
+  Arguments::assert_is_dumping_archive();
+  DumpTimeClassInfo* info = get_info_locked(k);
+  if (info != nullptr && info->_url_string == nullptr) {
+    info->copy_url_string(string_value);
+  }
+}
+
+void SystemDictionaryShared::save_timestamp(InstanceKlass* k, char* string_value) {
+  if (SystemDictionaryShared::is_regular_file(string_value)) {
+    char* dir = SystemDictionaryShared::get_filedir(string_value);
+    if (dir != nullptr) {
+      int64_t timestamp = SystemDictionaryShared::get_timestamp(dir, k->name());
+      SystemDictionaryShared::set_classfile_timestamp(k, timestamp);
+    } else {
+      log_trace(cds, aggressive)("Unsupported URL:%s", string_value);
+    }
+  } else if (!SystemDictionaryShared::is_jar_file(string_value)) {
+    log_trace(cds, aggressive)("Unsupported URL:%s", string_value);
+  }
+}
+
+void SystemDictionaryShared::set_classfile_timestamp(InstanceKlass* k, int64_t classfile_timestamp) {
+  assert(UseAggressiveCDS, "sanity");
+  Arguments::assert_is_dumping_archive();
+  DumpTimeClassInfo* info = get_info_locked(k);
+  if (info != nullptr) {
+    info->set_classfile_timestamp(classfile_timestamp);
+  }
+}
+
+int64_t SystemDictionaryShared::get_classfile_timestamp(InstanceKlass* k) {
+  assert(UseAggressiveCDS, "sanity");
+  RunTimeClassInfo* info = RunTimeClassInfo::get_for(k);
+  return info->classfile_timestamp();
+}
+
+InstanceKlass* SystemDictionaryShared::lookup_trusted_share_class(Symbol* class_name,
+                                                                  Handle class_loader,
+                                                                  TRAPS) {
+  assert(UseAggressiveCDS, "sanity");
+  if (!UseSharedSpaces) {
+    return nullptr;
+  }
+  if (class_name == nullptr) {
+    return nullptr;
+  }
+  if (class_loader.is_null() ||
+      SystemDictionary::is_system_class_loader(class_loader()) ||
+      SystemDictionary::is_platform_class_loader(class_loader())) {
+    return nullptr;
+  }
+
+  Handle lock = get_loader_lock_or_null(class_loader);
+  ObjectLocker ol(lock, THREAD);
+
+  register_loader(class_loader);
+
+  if (log_is_enabled(Info, cds)) {
+    ResourceMark rm(THREAD);
+    log_info(cds)("lookup_trusted_share_class %s: %s", class_name->as_C_string(),
+                                                       class_loader()->klass()->name()->as_C_string());
+  }
+
+  const RunTimeClassInfo* record = find_record(&_static_archive._unregistered_dictionary,
+                                               &_dynamic_archive._unregistered_dictionary,
+                                               class_name);
+  if (record == nullptr) {
+    log_info(cds)("not find class name : %s ", class_name->as_C_string());
+    return nullptr;
+  }
+
+  Handle protection_domain = SystemDictionaryShared::get_protection_domain(record->_klass, class_loader, CHECK_NULL);
+  if (protection_domain.is_null()) {
+    return nullptr;
+  }
+
+  InstanceKlass* k = acquire_class_for_current_thread(record->_klass, class_loader, protection_domain, nullptr, THREAD);
+  if (k != nullptr) {
+    SharedClassLoadingMark slm(THREAD, k);
+    find_or_define_instance_class(class_name, class_loader, k, CHECK_NULL);
+  }
+  return k;
+}
+#endif // INCLUDE_AGGRESSIVE_CDS
diff --git a/src/hotspot/share/classfile/systemDictionaryShared.hpp b/src/hotspot/share/classfile/systemDictionaryShared.hpp
index 27a0c74ed..9761d5e24 100644
--- a/src/hotspot/share/classfile/systemDictionaryShared.hpp
+++ b/src/hotspot/share/classfile/systemDictionaryShared.hpp
@@ -336,6 +336,23 @@ public:
   }
 
   static unsigned int hash_for_shared_dictionary(address ptr);
+
+#if INCLUDE_AGGRESSIVE_CDS
+  static bool is_jar_file(char* url_string);
+  static bool is_regular_file(char* url_string);
+  static char* get_filedir(char* url_string);
+  static int64_t get_timestamp(char* dir, Symbol* class_name);
+  static ClassFileStream* get_shared_class_file_stream(InstanceKlass* k);
+  static ClassFileStream* get_byte_code_from_cache(Symbol* class_name, Handle class_loader, TRAPS);
+  static void set_shared_class_file(InstanceKlass* k, ClassFileStream* cfs);
+  static Handle get_protection_domain(InstanceKlass* k, Handle class_loader, TRAPS);
+  static void set_url_string(InstanceKlass* k, char* string_value);
+  static void save_timestamp(InstanceKlass* k, char* string_value);
+  static void set_classfile_timestamp(InstanceKlass* k, int64_t classfile_timestamp);
+  static int64_t get_classfile_timestamp(InstanceKlass* k);
+
+  static InstanceKlass* lookup_trusted_share_class(Symbol* class_name, Handle class_loader, TRAPS);
+#endif // INCLUDE_AGGRESSIVE_CDS
 };
 
 #endif // SHARE_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP
diff --git a/src/hotspot/share/classfile/vmSymbols.hpp b/src/hotspot/share/classfile/vmSymbols.hpp
index bffffcaad..80baa7cf8 100644
--- a/src/hotspot/share/classfile/vmSymbols.hpp
+++ b/src/hotspot/share/classfile/vmSymbols.hpp
@@ -786,6 +786,9 @@
   template(toFileURL_name,                                  "toFileURL")                                          \
   template(toFileURL_signature,                             "(Ljava/lang/String;)Ljava/net/URL;")                 \
   template(url_void_signature,                              "(Ljava/net/URL;)V")                                  \
+  template(codesource_signature,                            "Ljava/security/CodeSource;")                         \
+  template(getProtectionDomainByURLString_name,             "getProtectionDomainByURLString")                     \
+  template(getProtectionDomainByURLString_signature,        "(Ljava/lang/String;)Ljava/security/ProtectionDomain;") \
                                                                                                                   \
   /* ElasticMaxDirectMemory */                                                                                    \
   template(java_nio_Bits,                          "java/nio/Bits")                                               \
diff --git a/src/hotspot/share/include/cds.h b/src/hotspot/share/include/cds.h
index af48c1a8c..9a0fdb210 100644
--- a/src/hotspot/share/include/cds.h
+++ b/src/hotspot/share/include/cds.h
@@ -37,6 +37,7 @@
 
 #define NUM_CDS_REGIONS 4 // this must be the same as MetaspaceShared::n_regions
 #define CDS_ARCHIVE_MAGIC 0xf00baba2
+#define CDS_AGGRESSIVE_ARCHIVE_MAGIC 0xf00baba4
 #define CDS_DYNAMIC_ARCHIVE_MAGIC 0xf00baba8
 #define CDS_GENERIC_HEADER_SUPPORTED_MIN_VERSION 13
 #define CURRENT_CDS_ARCHIVE_VERSION 18
diff --git a/src/hotspot/share/include/jvm.h b/src/hotspot/share/include/jvm.h
index 73e29bcf2..48363d0b7 100644
--- a/src/hotspot/share/include/jvm.h
+++ b/src/hotspot/share/include/jvm.h
@@ -1203,6 +1203,11 @@ typedef struct JDK1_1InitArgs {
     jint debugPort;
 } JDK1_1InitArgs;
 
+/**
+ * Define the trusted shared class.
+ */
+JNIEXPORT jclass JNICALL
+JVM_DefineTrustedSharedClass(JNIEnv *env, const char *name, jobject loader);
 
 #ifdef __cplusplus
 } /* extern "C" */
diff --git a/src/hotspot/share/logging/logTag.hpp b/src/hotspot/share/logging/logTag.hpp
index 6e656de0c..7ac95640c 100644
--- a/src/hotspot/share/logging/logTag.hpp
+++ b/src/hotspot/share/logging/logTag.hpp
@@ -36,6 +36,7 @@ class outputStream;
 #define LOG_TAG_LIST \
   LOG_TAG(add) \
   LOG_TAG(age) \
+  AGGRESSIVE_CDS_ONLY(LOG_TAG(aggressive)) \
   LOG_TAG(alloc) \
   LOG_TAG(annotation) \
   LOG_TAG(arguments) \
diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp
index 553869ec9..7eaccfeea 100644
--- a/src/hotspot/share/oops/instanceKlass.cpp
+++ b/src/hotspot/share/oops/instanceKlass.cpp
@@ -2506,6 +2506,30 @@ void InstanceKlass::clean_weak_instanceklass_links() {
   clean_method_data();
 }
 
+#if INCLUDE_AGGRESSIVE_CDS
+bool InstanceKlass::has_stored_fingerprint() const {
+  return Arguments::is_dumping_archive() || is_shared();
+}
+
+uint64_t InstanceKlass::get_stored_fingerprint() const {
+  address adr = adr_fingerprint();
+  if (adr != nullptr) {
+    return (uint64_t)Bytes::get_native_u8(adr); // adr may not be 64-bit aligned
+  }
+  return 0;
+}
+
+void InstanceKlass::store_fingerprint(uint64_t fingerprint) {
+  address adr = adr_fingerprint();
+  if (adr != nullptr) {
+    Bytes::put_native_u8(adr, (u8)fingerprint); // adr may not be 64-bit aligned
+
+    ResourceMark rm;
+    log_trace(class, fingerprint)("stored as " UINT64_FORMAT_X_0 " for class %s", fingerprint, external_name());
+  }
+}
+#endif
+
 void InstanceKlass::clean_implementors_list() {
   assert(is_loader_alive(), "this klass should be live");
   if (is_interface()) {
diff --git a/src/hotspot/share/oops/instanceKlass.hpp b/src/hotspot/share/oops/instanceKlass.hpp
index 0a23c3454..0f55e093b 100644
--- a/src/hotspot/share/oops/instanceKlass.hpp
+++ b/src/hotspot/share/oops/instanceKlass.hpp
@@ -1013,6 +1013,13 @@ public:
   void adjust_default_methods(bool* trace_name_printed);
 #endif // INCLUDE_JVMTI
 
+#if INCLUDE_AGGRESSIVE_CDS
+  inline address adr_fingerprint() const;
+  bool has_stored_fingerprint() const;
+  uint64_t get_stored_fingerprint() const;
+  void store_fingerprint(uint64_t fingerprint);
+#endif
+
   void clean_weak_instanceklass_links();
  private:
   void clean_implementors_list();
diff --git a/src/hotspot/share/oops/instanceKlass.inline.hpp b/src/hotspot/share/oops/instanceKlass.inline.hpp
index 8258dd4e0..a9c9d9608 100644
--- a/src/hotspot/share/oops/instanceKlass.inline.hpp
+++ b/src/hotspot/share/oops/instanceKlass.inline.hpp
@@ -66,6 +66,21 @@ inline InstanceKlass* volatile* InstanceKlass::adr_implementor() const {
   }
 }
 
+#if INCLUDE_AGGRESSIVE_CDS
+inline address InstanceKlass::adr_fingerprint() const {
+  if (has_stored_fingerprint()) {
+    InstanceKlass* volatile* adr_impl = adr_implementor();
+    if (adr_impl != nullptr) {
+      return (address)(adr_impl + 1);
+    } else {
+      return (address)end_of_nonstatic_oop_maps();
+    }
+  } else {
+    return nullptr;
+  }
+}
+#endif
+
 inline ObjArrayKlass* InstanceKlass::array_klasses_acquire() const {
   return Atomic::load_acquire(&_array_klasses);
 }
diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp
index 7f0eddbda..a96a53f51 100644
--- a/src/hotspot/share/prims/jvm.cpp
+++ b/src/hotspot/share/prims/jvm.cpp
@@ -3922,6 +3922,27 @@ JVM_LEAF(jint, JVM_FindSignal(const char *name))
   return os::get_signal_number(name);
 JVM_END
 
+JVM_ENTRY(jclass, JVM_DefineTrustedSharedClass(JNIEnv *env, const char *name, jobject loader))
+#if INCLUDE_AGGRESSIVE_CDS
+  assert(UseAggressiveCDS, "sanity");
+  TempNewSymbol class_name = name == nullptr ? nullptr :
+      SystemDictionary::class_name_symbol(name,
+                                          vmSymbols::java_lang_NoClassDefFoundError(),
+                                          CHECK_NULL);
+  Handle class_loader (THREAD, JNIHandles::resolve(loader));
+  InstanceKlass* k = SystemDictionaryShared::lookup_trusted_share_class(class_name,
+                                                                        class_loader,
+                                                                        CHECK_NULL);
+  if (k == nullptr) {
+    return nullptr;
+  }
+
+  return (jclass) JNIHandles::make_local(THREAD, k->java_mirror());
+#else
+  return nullptr;
+#endif // INCLUDE_AGGRESSIVE_CDS
+JVM_END
+
 JVM_ENTRY(void, JVM_VirtualThreadStart(JNIEnv* env, jobject vthread))
 #if INCLUDE_JVMTI
   if (!DoJVMTIVirtualThreadTransitions) {
diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp
index 4a9f9b2bb..f17f5f984 100644
--- a/src/hotspot/share/runtime/arguments.cpp
+++ b/src/hotspot/share/runtime/arguments.cpp
@@ -3518,6 +3518,44 @@ void Arguments::set_shared_spaces_flags_and_archive_paths() {
 
 #if INCLUDE_CDS
 // Sharing support
+
+static bool is_same_default_archive_path(const char* jvm_path, const char* archive_path, const char* name) {
+  stringStream path;
+  path.print("%s%s%s", jvm_path, os::file_separator(), name);
+  return os::same_files(path.base(), archive_path);
+}
+
+bool Arguments::is_default_archive_path(const char* archive_path) {
+  if (archive_path == nullptr) {
+    return false;
+  }
+
+  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';
+
+  if (is_same_default_archive_path(jvm_path, archive_path, "classes.jsa")) {
+    return true;
+  }
+
+#ifdef _LP64
+  if (is_same_default_archive_path(jvm_path, archive_path, "classes_nocoops.jsa")) {
+    return true;
+  }
+
+  if (is_same_default_archive_path(jvm_path, archive_path, "classes_coh.jsa")) {
+    return true;
+  }
+
+  if (is_same_default_archive_path(jvm_path, archive_path, "classes_nocoops_coh.jsa")) {
+    return true;
+  }
+#endif
+
+  return false;
+}
+
 // Construct the path to the archive
 char* Arguments::get_default_shared_archive_path() {
   if (_default_shared_archive_path == nullptr) {
@@ -3594,9 +3632,9 @@ void Arguments::init_shared_archive_paths() {
     }
     check_unsupported_dumping_properties();
 
-    if (os::same_files(get_default_shared_archive_path(), ArchiveClassesAtExit)) {
+    if (is_default_archive_path(ArchiveClassesAtExit)) {
       vm_exit_during_initialization(
-        "Cannot specify the default CDS archive for -XX:ArchiveClassesAtExit", get_default_shared_archive_path());
+        "Cannot specify the default CDS archive for -XX:ArchiveClassesAtExit", ArchiveClassesAtExit);
     }
   }
 
@@ -4168,6 +4206,11 @@ jint Arguments::apply_ergo() {
 
   set_shared_spaces_flags_and_archive_paths();
 
+#if INCLUDE_AGGRESSIVE_CDS
+  result = init_aggressive_cds_properties();
+  if (result != JNI_OK) return result;
+#endif // INCLUDE_AGGRESSIVE_CDS
+
   // Initialize Metaspace flags and alignments
   Metaspace::ergo_initialize();
 
@@ -4427,3 +4470,16 @@ bool Arguments::copy_expand_pid(const char* src, size_t srclen,
   *b = '\0';
   return (p == src_end); // return false if not all of the source was copied
 }
+
+#if INCLUDE_AGGRESSIVE_CDS
+
+jint Arguments::init_aggressive_cds_properties() {
+  if (!is_dumping_archive() && SharedDynamicArchivePath != nullptr && UseAggressiveCDS) {
+    bool added = false;
+    added = add_property("jdk.jbooster.aggressivecds.load=true", UnwriteableProperty, InternalProperty);
+    if (!added) return JNI_ENOMEM;
+  }
+  return JNI_OK;
+}
+
+#endif // INCLUDE_AGGRESSIVE_CDS
diff --git a/src/hotspot/share/runtime/arguments.hpp b/src/hotspot/share/runtime/arguments.hpp
index 977422a29..03778c17f 100644
--- a/src/hotspot/share/runtime/arguments.hpp
+++ b/src/hotspot/share/runtime/arguments.hpp
@@ -500,6 +500,7 @@ class Arguments : AllStatic {
   static void  fix_appclasspath();
 
   static char* get_default_shared_archive_path() NOT_CDS_RETURN_(nullptr);
+  static bool  is_default_archive_path(const char* archive_path) NOT_CDS_RETURN_(false);
   static void  init_shared_archive_paths() NOT_CDS_RETURN;
 
   // Operation modi
@@ -529,6 +530,10 @@ class Arguments : AllStatic {
     assert(Arguments::is_dumping_archive(), "dump time only");
   }
 
+#if INCLUDE_AGGRESSIVE_CDS
+  static jint init_aggressive_cds_properties();
+#endif // INCLUDE_AGGRESSIVE_CDS
+
   DEBUG_ONLY(static bool verify_special_jvm_flags(bool check_globals);)
 };
 
diff --git a/src/hotspot/share/runtime/threads.cpp b/src/hotspot/share/runtime/threads.cpp
index 8c242b3ba..5f4263eab 100644
--- a/src/hotspot/share/runtime/threads.cpp
+++ b/src/hotspot/share/runtime/threads.cpp
@@ -490,6 +490,8 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
 
   os::init_before_ergo();
 
+  AARCH64_ONLY(JavaThread::handle_appcds_for_executor(args));
+
   jint ergo_result = Arguments::apply_ergo();
   if (ergo_result != JNI_OK) return ergo_result;
 
diff --git a/src/hotspot/share/utilities/macros.hpp b/src/hotspot/share/utilities/macros.hpp
index 8526d95fb..a72e91db4 100644
--- a/src/hotspot/share/utilities/macros.hpp
+++ b/src/hotspot/share/utilities/macros.hpp
@@ -129,6 +129,20 @@
 #define NOT_CDS_RETURN_(code) { return code; }
 #endif // INCLUDE_CDS
 
+#ifndef INCLUDE_AGGRESSIVE_CDS
+#if INCLUDE_CDS && defined(AARCH64)
+#define INCLUDE_AGGRESSIVE_CDS 1
+#else
+#define INCLUDE_AGGRESSIVE_CDS 0
+#endif
+#endif // INCLUDE_AGGRESSIVE_CDS
+
+#if INCLUDE_AGGRESSIVE_CDS
+#define AGGRESSIVE_CDS_ONLY(x) x
+#else
+#define AGGRESSIVE_CDS_ONLY(x)
+#endif // INCLUDE_AGGRESSIVE_CDS
+
 #ifndef INCLUDE_JBOLT
 #define INCLUDE_JBOLT 1
 #endif
diff --git a/src/java.base/share/classes/java/lang/ClassLoader.java b/src/java.base/share/classes/java/lang/ClassLoader.java
index 079a40acc..901cc86e5 100644
--- a/src/java.base/share/classes/java/lang/ClassLoader.java
+++ b/src/java.base/share/classes/java/lang/ClassLoader.java
@@ -940,6 +940,21 @@ public abstract class ClassLoader {
         }
     }
 
+    /**
+     * Determine protection domain, and check it.
+     * This method is only for AggressiveCDS.
+     *
+     * @param   name the name of the class
+     * @param   c the class
+     * @param   pd the ProtectionDomain of the class
+     */
+    protected void defineClassProtectionDomain(String name, Class<?> c, ProtectionDomain pd)
+    {
+        // Determine protection domain
+        pd = preDefineClass(name, pd);
+        postDefineClass(c, pd);
+    }
+
     /**
      * Converts an array of bytes into an instance of class {@code Class},
      * with a given {@code ProtectionDomain}.
@@ -1127,6 +1142,11 @@ public abstract class ClassLoader {
                                         int off, int len, ProtectionDomain pd,
                                         String source);
 
+    /**
+     * This method is only invoked in java.net.AggressiveCDSPlugin.
+     */
+    private static native Class<?> defineClass3(ClassLoader loader, String name);
+
     /**
      * Defines a class of the given flags via Lookup.defineClass.
      *
diff --git a/src/java.base/share/classes/java/net/AggressiveCDSPlugin.java b/src/java.base/share/classes/java/net/AggressiveCDSPlugin.java
new file mode 100644
index 000000000..b9fcc630c
--- /dev/null
+++ b/src/java.base/share/classes/java/net/AggressiveCDSPlugin.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import jdk.internal.loader.Resource;
+import jdk.internal.loader.URLClassPath;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.reflect.Method;
+
+import sun.security.action.GetBooleanAction;
+
+/**
+ * The Aggressive CDS plugin for {@link java.net.URLClassLoader}.
+ */
+final class AggressiveCDSPlugin {
+    private static final boolean IS_ENABLED = GetBooleanAction.privilegedGetProperty("jdk.jbooster.aggressivecds.load");
+
+    /**
+     * Check whether Aggressive CDS is enabled.
+     *
+     * @return Is Aggressive CDS enabled
+     */
+    public static boolean isEnabled() {
+        return IS_ENABLED;
+    }
+
+    /**
+     * Define the class by Aggressive CDS. The class is trusted and shared,
+     *
+     * @param   loader The class loader of the class (should be URLClassLoader)
+     * @param   name The name of the class
+     * @return  The defined class, or null if not found
+     */
+    public static Class<?> defineTrustedSharedClass(URLClassLoader loader, String name) {
+        return ClassLoaderUtil.defineClass3(loader, name);
+    }
+
+    /**
+     * get URL from URLClassPath by Aggressive CDS.
+     *
+     * @param   ucp The URLClassPath
+     * @param   urlNoFragString The name string of the url
+     * @return  The URL, or null if not found
+     */
+    public static URL getURLFromURLClassPath(URLClassPath ucp, String urlNoFragString) {
+        return URLClassPathTool.getURL(ucp, urlNoFragString);
+    }
+
+    /**
+     * Finds the byte code with the specified name on the URL search path.
+     * This method is invoked only in C++ ({@code SystemDictionaryShared::get_byte_code_from_cache}).
+     *
+     * @param   loader The class loader of the class
+     * @param   name The name of the class
+     * @return  Byte code of the resource, or {@code null} if not found
+     * @throws  IOException Resource.getBytes()
+     */
+    private static byte[] getByteCodeFromCache(URLClassLoader loader, String name) throws IOException {
+        String path = name.replace('.', '/').concat(".class");
+        Resource resource = getResourceFromCache(loader, path);
+        if (resource == null) {
+            return null;
+        } else {
+            return resource.getBytes();
+        }
+    }
+
+    /**
+     * Finds the byte code with the specified name on the URL search path.
+     * This method is invoked only in C++.
+     *
+     * @param   loader The class loader of the class
+     * @param   name The name of the class
+     * @return  The resource in cache
+     */
+    private static Resource getResourceFromCache(URLClassLoader loader, final String name) {
+        URL url = loader.findResource(name);
+        if (url == null) {
+            return null;
+        }
+        final URLConnection uc;
+        try {
+            uc = url.openConnection();
+        } catch (IOException e) {
+            return null;
+        }
+        return new Resource() {
+            @Override
+            public String getName() {
+                return name;
+            }
+
+            @Override
+            public URL getURL() {
+                return url;
+            }
+
+            @Override
+            public URL getCodeSourceURL() {
+                return url;
+            }
+
+            @Override
+            public InputStream getInputStream() throws IOException {
+                return uc.getInputStream();
+            }
+
+            @Override
+            public int getContentLength() throws IOException {
+                return uc.getContentLength();
+            }
+        };
+    }
+}
+
+/**
+ * We don't want to add new public methods in {@link java.lang.ClassLoader}. So we add
+ * a private method (defineClass3) and use a method handle to invoke it.
+ */
+final class ClassLoaderUtil {
+    private static final MethodHandle classDefiner3;
+
+    static {
+        MethodHandle mh3 = null;
+        try {
+            MethodHandles.Lookup lookup = MethodHandles.lookup();
+            Method m3 = ClassLoader.class.getDeclaredMethod("defineClass3", ClassLoader.class, String.class);
+            m3.setAccessible(true);
+            mh3 = lookup.unreflect(m3);
+        } catch (NoSuchMethodException | IllegalAccessException e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+        classDefiner3 = mh3;
+    }
+
+    public static Class<?> defineClass3(ClassLoader loader, String name) {
+        try {
+            return (Class<?>) classDefiner3.invoke(loader, name);
+        } catch (Throwable throwable) {
+            throwable.printStackTrace();
+            System.exit(1);
+        }
+        return null;
+    }
+}
+
+/**
+ * We don't want to add new public methods in {@link jdk.internal.loader.URLClassPath}. So we add
+ * a private method (getURL) and use a method handle to invoke it.
+ */
+final class URLClassPathTool {
+    private static final MethodHandle getURLMethodHandle;
+
+    static {
+        MethodHandle getURL = null;
+        try {
+            MethodHandles.Lookup lookup = MethodHandles.lookup();
+            Method getURLMethod = URLClassPath.class.getDeclaredMethod("getURL", String.class);
+            getURLMethod.setAccessible(true);
+            getURL = lookup.unreflect(getURLMethod);
+        } catch (NoSuchMethodException | IllegalAccessException e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+        getURLMethodHandle = getURL;
+    }
+
+    public static URL getURL(URLClassPath ucp, String urlNoFragString) {
+        try {
+            return (URL) getURLMethodHandle.invoke(ucp, urlNoFragString);
+        } catch (Throwable throwable) {
+            throwable.printStackTrace();
+            System.exit(1);
+        }
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/src/java.base/share/classes/java/net/URLClassLoader.java b/src/java.base/share/classes/java/net/URLClassLoader.java
index 97c95bc9f..8314d5bb3 100644
--- a/src/java.base/share/classes/java/net/URLClassLoader.java
+++ b/src/java.base/share/classes/java/net/URLClassLoader.java
@@ -38,6 +38,7 @@ import java.security.Permission;
 import java.security.PermissionCollection;
 import java.security.PrivilegedAction;
 import java.security.PrivilegedExceptionAction;
+import java.security.ProtectionDomain;
 import java.security.SecureClassLoader;
 import java.util.Enumeration;
 import java.util.List;
@@ -420,6 +421,17 @@ public class URLClassLoader extends SecureClassLoader implements Closeable {
             result = AccessController.doPrivileged(
                 new PrivilegedExceptionAction<>() {
                     public Class<?> run() throws ClassNotFoundException {
+                        if (AggressiveCDSPlugin.isEnabled()) {
+                            try {
+                                Class<?> trustedClass = AggressiveCDSPlugin
+                                        .defineTrustedSharedClass(URLClassLoader.this, name);
+                                if (trustedClass != null) {
+                                    ProtectionDomain pd = trustedClass.getProtectionDomain();
+                                    defineClassProtectionDomain(name, trustedClass, pd);
+                                    return trustedClass;
+                                }
+                            } catch (Throwable ignored) {}
+                        }
                         String path = name.replace('.', '/').concat(".class");
                         Resource res = ucp.getResource(path, false);
                         if (res != null) {
@@ -447,6 +459,24 @@ public class URLClassLoader extends SecureClassLoader implements Closeable {
         return result;
     }
 
+    /**
+     * get ProtectionDomain By URL String.
+     * This method is invoked only in C++ for AggressiveCDS.
+     *
+     * @param urlNoFragString the URL String.
+     *
+     * @return ProtectionDomain create from URL.
+     */
+    private ProtectionDomain getProtectionDomainByURLString(String urlNoFragString) {
+        if (AggressiveCDSPlugin.isEnabled()) {
+            URL url = AggressiveCDSPlugin.getURLFromURLClassPath(ucp, urlNoFragString);
+            if (url != null) {
+                return getProtectionDomainFromURL(url);
+            }
+        }
+        return null;
+    }
+
     /*
      * Retrieve the package using the specified package name.
      * If non-null, verify the package using the specified code
diff --git a/src/java.base/share/classes/java/security/SecureClassLoader.java b/src/java.base/share/classes/java/security/SecureClassLoader.java
index 682edf8e1..85713088a 100644
--- a/src/java.base/share/classes/java/security/SecureClassLoader.java
+++ b/src/java.base/share/classes/java/security/SecureClassLoader.java
@@ -27,6 +27,7 @@ package java.security;
 
 import sun.security.util.Debug;
 
+import java.net.URL;
 import java.util.Map;
 import java.util.Objects;
 import java.util.concurrent.ConcurrentHashMap;
@@ -236,6 +237,19 @@ public class SecureClassLoader extends ClassLoader {
         });
     }
 
+    /**
+     * get ProtectionDomain From URL.
+     * This method is only for AggressiveCDS.
+     *
+     * @param url the URL.
+     *
+     * @return ProtectionDomain create from URL.
+     */
+    protected ProtectionDomain getProtectionDomainFromURL(URL url) {
+        CodeSource cs = new CodeSource(url, (CodeSigner[]) null);
+        return getProtectionDomain(cs);
+    }
+
     private record CodeSourceKey(CodeSource cs) {
 
         @Override
diff --git a/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java b/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java
index bf123511f..9bb3cd743 100644
--- a/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java
+++ b/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java
@@ -321,6 +321,24 @@ public class URLClassPath {
         return null;
     }
 
+    /**
+     * Finds the URL which has the specified name.
+     * This method is only for AggressiveCDS.
+     *
+     * @param urlNoFragString the name of URL
+     * @return the URL, or null if not found
+     */
+    private URL getURL(String urlNoFragString) {
+        if (!unopenedUrls.isEmpty()) {
+            int index = loaders.size();
+            while(getLoader(index) != null) {
+                index++;
+            }
+        }
+        Loader loader = lmap.get(urlNoFragString);
+        return loader != null ? loader.getBaseURL() : null;
+    }
+
     /**
      * Finds all resources on the URL search path with the given name.
      * Returns an enumeration of the URL objects.
diff --git a/src/java.base/share/native/libjava/ClassLoader.c b/src/java.base/share/native/libjava/ClassLoader.c
index 927432d15..75f6ff06a 100644
--- a/src/java.base/share/native/libjava/ClassLoader.c
+++ b/src/java.base/share/native/libjava/ClassLoader.c
@@ -327,3 +327,29 @@ Java_java_lang_ClassLoader_findLoadedClass0(JNIEnv *env, jobject loader,
         return JVM_FindLoadedClass(env, loader, name);
     }
 }
+
+JNIEXPORT jclass JNICALL
+Java_java_lang_ClassLoader_defineClass3(JNIEnv *env,
+                                               jclass cls,
+                                               jobject loader,
+                                               jstring name)
+{
+    jclass result = 0;
+    char *utfName;
+    char buf[128];
+
+    if (name != NULL) {
+        utfName = getUTF(env, name, buf, sizeof(buf));
+        if (utfName == NULL) {
+            JNU_ThrowOutOfMemoryError(env, NULL);
+            return result;
+        }
+        fixClassname(utfName);
+    } else {
+        utfName = NULL;
+    }
+
+    result = JVM_DefineTrustedSharedClass(env, utfName, loader);
+
+    return result;
+}
-- 
2.17.1