diff a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp
--- a/src/hotspot/share/classfile/systemDictionary.cpp
+++ b/src/hotspot/share/classfile/systemDictionary.cpp
@@ -54,10 +54,11 @@
 #include "memory/metaspaceClosure.hpp"
 #include "memory/oopFactory.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
 #include "oops/access.inline.hpp"
+#include "oops/fieldStreams.inline.hpp"
 #include "oops/instanceKlass.hpp"
 #include "oops/klass.inline.hpp"
 #include "oops/method.inline.hpp"
 #include "oops/objArrayKlass.hpp"
 #include "oops/objArrayOop.inline.hpp"
@@ -65,18 +66,20 @@
 #include "oops/oop.hpp"
 #include "oops/oopHandle.hpp"
 #include "oops/oopHandle.inline.hpp"
 #include "oops/symbol.hpp"
 #include "oops/typeArrayKlass.hpp"
+#include "oops/inlineKlass.inline.hpp"
 #include "prims/jvmtiExport.hpp"
 #include "prims/methodHandles.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/java.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/mutexLocker.hpp"
+#include "runtime/os.hpp"
 #include "runtime/sharedRuntime.hpp"
 #include "runtime/signature.hpp"
 #include "runtime/synchronizer.hpp"
 #include "services/classLoadingService.hpp"
 #include "services/diagnosticCommand.hpp"
@@ -347,11 +350,11 @@
     return resolve_array_class_or_null(class_name, class_loader, protection_domain, THREAD);
   } else {
     assert(class_name != nullptr && !Signature::is_array(class_name), "must be");
     if (Signature::has_envelope(class_name)) {
       ResourceMark rm(THREAD);
-      // Ignore wrapping L and ;.
+      // Ignore wrapping L and ; (and Q and ; for value types).
       TempNewSymbol name = SymbolTable::new_symbol(class_name->as_C_string() + 1,
                                                    class_name->utf8_length() - 2);
       return resolve_instance_class_or_null(name, class_loader, protection_domain, THREAD);
     } else {
       return resolve_instance_class_or_null(class_name, class_loader, protection_domain, THREAD);
@@ -452,10 +455,11 @@
     MutexLocker mu(THREAD, SystemDictionary_lock);
     InstanceKlass* klassk = dictionary->find_class(THREAD, class_name);
     InstanceKlass* quicksuperk;
     // To support parallel loading: if class is done loading, just return the superclass
     // if the next_name matches class->super()->name() and if the class loaders match.
+    // Otherwise, a LinkageError will be thrown later.
     if (klassk != nullptr && is_superclass &&
        ((quicksuperk = klassk->java_super()) != nullptr) &&
        ((quicksuperk->name() == next_name) &&
          (quicksuperk->class_loader() == class_loader()))) {
       return quicksuperk;
@@ -944,12 +948,11 @@
 // Check if a shared class can be loaded by the specific classloader.
 bool SystemDictionary::is_shared_class_visible(Symbol* class_name,
                                                InstanceKlass* ik,
                                                PackageEntry* pkg_entry,
                                                Handle class_loader) {
-  assert(!ModuleEntryTable::javabase_moduleEntry()->is_patched(),
-         "Cannot use sharing if java.base is patched");
+  assert(!CDSConfig::module_patching_disables_cds(), "Cannot use CDS");
 
   // (1) Check if we are loading into the same loader as in dump time.
 
   if (ik->is_shared_boot_class()) {
     if (class_loader() != nullptr) {
@@ -1021,11 +1024,11 @@
   if (was_archived_from_named_module) {
     if (should_be_in_named_module) {
       // Is the module loaded from the same location as during dump time?
       visible = mod_entry->shared_path_index() == scp_index;
       if (visible) {
-        assert(!mod_entry->is_patched(), "cannot load archived classes for patched module");
+        assert(!CDSConfig::module_patching_disables_cds(), "Cannot use CDS");
       }
     } else {
       // During dump time, this class was in a named module, but at run time, this class should be
       // in an unnamed module.
       visible = false;
@@ -1155,10 +1158,42 @@
   if (!check) {
     ik->set_shared_loading_failed();
     return nullptr;
   }
 
+  if (ik->has_inline_type_fields()) {
+    for (AllFieldStream fs(ik); !fs.done(); fs.next()) {
+      if (fs.access_flags().is_static()) continue;
+      Symbol* sig = fs.signature();
+      if (fs.is_null_free_inline_type()) {
+        // Pre-load inline class
+        TempNewSymbol name = Signature::strip_envelope(sig);
+        Klass* real_k = SystemDictionary::resolve_with_circularity_detection_or_fail(ik->name(), name,
+          class_loader, protection_domain, false, CHECK_NULL);
+        Klass* k = ik->get_inline_type_field_klass_or_null(fs.index());
+        if (real_k != k) {
+          // oops, the app has substituted a different version of k!
+          return nullptr;
+        }
+      } else if (Signature::has_envelope(sig)) {
+        TempNewSymbol name = Signature::strip_envelope(sig);
+        if (name != ik->name() && ik->is_class_in_loadable_descriptors_attribute(name)) {
+          Klass* real_k = SystemDictionary::resolve_with_circularity_detection_or_fail(ik->name(), name,
+            class_loader, protection_domain, false, THREAD);
+          if (HAS_PENDING_EXCEPTION) {
+            CLEAR_PENDING_EXCEPTION;
+          }
+          Klass* k = ik->get_inline_type_field_klass_or_null(fs.index());
+          if (real_k != k) {
+            // oops, the app has substituted a different version of k!
+            return nullptr;
+          }
+        }
+      }
+    }
+  }
+
   InstanceKlass* new_ik = nullptr;
   // CFLH check is skipped for VM hidden classes (see KlassFactory::create_from_stream).
   // It will be skipped for shared VM hidden lambda proxy classes.
   if (!SystemDictionaryShared::is_hidden_lambda_proxy(ik)) {
     new_ik = KlassFactory::check_shared_class_file_load_hook(
@@ -1190,10 +1225,11 @@
     // restore_unshareable_info which calls ik->set_package()
     ik->restore_unshareable_info(loader_data, protection_domain, pkg_entry, CHECK_NULL);
   }
 
   load_shared_class_misc(ik, loader_data);
+
   return ik;
 }
 
 void SystemDictionary::load_shared_class_misc(InstanceKlass* ik, ClassLoaderData* loader_data) {
   ik->print_class_load_logging(loader_data, nullptr, nullptr);
