diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp
index f27d04d0..306315e9 100644
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp
@@ -4022,8 +4022,12 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
       if (_host_klass == NULL && SystemDictionaryShared::is_sharing_possible(loader_data)) {
         if (name != NULL) {
           ResourceMark rm(THREAD);
-          classlist_file->print_cr("%s", name->as_C_string());
-          classlist_file->flush();
+          char *class_name = name->as_C_string();
+          // TODO Skip JFR-related classes in classlist file to avoid conflicts between appcds and jfr.
+          if ((class_name != NULL) && (strstr(class_name, "jfr") == NULL)) {
+            classlist_file->print_cr("%s", class_name);
+            classlist_file->flush();
+          }
         }
       }
     }
diff --git a/hotspot/src/share/vm/classfile/systemDictionary.cpp b/hotspot/src/share/vm/classfile/systemDictionary.cpp
index d27bf484..3f28d38e 100644
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp
@@ -1283,41 +1283,43 @@ instanceKlassHandle SystemDictionary::load_shared_class(
       // null) or the same class loader is used to load previously
       // defined class
       bool bFound = false;
-        if (class_loader.is_null()) {
-          // condition1: Bootstrap class loader loaded
-          bFound = (ik()->class_loader_data() == NULL || ik()->class_loader_data()->is_the_null_class_loader_data());
-        } else if (ik()->class_loader_data() != NULL) {
-          // condition2: App Class Loader
-          // condition3: ExtClass Loader
-          // Condition4: not fake class Loader, real one
-          bFound = ((ik->has_fake_loader_data_App() && SystemDictionary::is_app_class_loader(class_loader)) ||
-                    (ik->has_fake_loader_data_Ext() && SystemDictionary::is_ext_class_loader(class_loader)) ||
-                    (!ik->has_fake_loader_data() && ik()->class_loader() == class_loader()));
-          }
-          if (!bFound) {
-            return instanceKlassHandle();
-          }
+      if (class_loader.is_null()) {
+        // condition1: Bootstrap class loader loaded
+        bFound = (ik()->class_loader_data() == NULL || ik()->class_loader_data()->is_the_null_class_loader_data());
+      } else if (ik()->class_loader_data() != NULL) {
+        // condition2: App Class Loader
+        // condition3: ExtClass Loader
+        // condition4: not fake class Loader, real one
+        bFound = ((ik->has_fake_loader_data_App() && SystemDictionary::is_app_class_loader(class_loader)) ||
+                  (ik->has_fake_loader_data_Ext() && SystemDictionary::is_ext_class_loader(class_loader)) ||
+                  (!ik->has_fake_loader_data() && ik()->class_loader() == class_loader()));
+      }
+      if (!bFound) {
+        return instanceKlassHandle();
+      }
 
-          // get protection domain for this class if not loaded by null class loader
-          if (class_loader.not_null()) {
-            ResourceMark rm(THREAD);
-            char* name = ik->name()->as_C_string();
-            Handle klass_name = java_lang_String::create_from_str(name, CHECK_0);
-            JavaValue result(T_OBJECT);
-
-            // ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(class_loader());
-            JavaCalls::call_virtual(&result,
-                                    class_loader,
-                                    KlassHandle(THREAD, SystemDictionary::URLClassLoader_klass()),
-                                    vmSymbols::getProtectionDomainInternal_name(),
-                                    vmSymbols::getProtectionDomainInternal_signature(),
-                                    klass_name,
-                                    THREAD);
-            return load_shared_class(ik, class_loader, Handle(THREAD, (oop) result.get_jobject()), THREAD);
-          } else {
-            return load_shared_class(ik, class_loader, Handle(), THREAD);
-          }
+      // get protection domain for this class if not loaded by null class loader
+      if (class_loader.not_null()) {
+        ResourceMark rm(THREAD);
+        char* name = ik->name()->as_C_string();
+        Handle klass_name = java_lang_String::create_from_str(name, CHECK_0);
+        JavaValue result(T_OBJECT);
+
+	// load_shared_class need protected domain to handle non-bootstrap loaded class,
+        // so here call_virtual to call getProtectionDomainInternal function of URLClassLoader.java,
+        // to get protected domain and save into result.
+        JavaCalls::call_virtual(&result,
+                                class_loader,
+                                KlassHandle(THREAD, SystemDictionary::URLClassLoader_klass()),
+                                vmSymbols::getProtectionDomainInternal_name(),
+                                vmSymbols::getProtectionDomainInternal_signature(),
+                                klass_name,
+                                THREAD);
+        return load_shared_class(ik, class_loader, Handle(THREAD, (oop) result.get_jobject()), THREAD);
+      } else {
+        return load_shared_class(ik, class_loader, Handle(), THREAD);
       }
+    }
   }
   return instanceKlassHandle();
 }
@@ -1396,8 +1398,12 @@ instanceKlassHandle SystemDictionary::load_shared_class(instanceKlassHandle ik,
       // unless AppCDS is enabled
       if (SystemDictionaryShared::is_sharing_possible(loader_data)) {
         ResourceMark rm(THREAD);
-        classlist_file->print_cr("%s", ik->name()->as_C_string());
-        classlist_file->flush();
+        char *class_name = ik->name()->as_C_string();
+        // TODO Skip JFR-related classes in classlist file to avoid conflicts between appcds and jfr.
+        if ((class_name != NULL) && (strstr(class_name, "jfr") == NULL)) {
+          classlist_file->print_cr("%s", class_name);
+          classlist_file->flush();
+        }
       }
     }
 
@@ -1472,8 +1478,10 @@ instanceKlassHandle SystemDictionary::load_instance_class(Symbol* class_name, Ha
       // the call stack. Bootstrap classloader is parallel-capable,
       // so no concurrency issues are expected.
       CLEAR_PENDING_EXCEPTION;
-      k = JfrUpcalls::load_event_handler_proxy_class(THREAD);
-      assert(!k.is_null(), "invariant");
+      if (!DumpSharedSpaces) {
+        k = JfrUpcalls::load_event_handler_proxy_class(THREAD);
+        assert(!k.is_null(), "invariant");
+      }
     }
 #endif
 
diff --git a/hotspot/src/share/vm/classfile/systemDictionaryShared.hpp b/hotspot/src/share/vm/classfile/systemDictionaryShared.hpp
index a8dbda2e..1bd61b02 100644
--- a/hotspot/src/share/vm/classfile/systemDictionaryShared.hpp
+++ b/hotspot/src/share/vm/classfile/systemDictionaryShared.hpp
@@ -28,6 +28,7 @@
 
 #include "classfile/dictionary.hpp"
 #include "classfile/systemDictionary.hpp"
+#include "verifier.hpp"
 
 class SystemDictionaryShared: public SystemDictionary {
 public:
@@ -70,7 +71,16 @@ public:
   static void finalize_verification_dependencies() {}
   static bool check_verification_dependencies(Klass* k, Handle class_loader,
                                               Handle protection_domain,
-                                              char** message_buffer, TRAPS) {return true;}
+                                              char** message_buffer, TRAPS) {
+    if (EnableSplitVerifierForAppCDS) {
+      ClassVerifier split_verifier(k, THREAD);
+      split_verifier.verify_class(THREAD);
+      if (HAS_PENDING_EXCEPTION) {
+        return false; // use the existing exception
+      }
+    }
+    return true;
+  }
 };
 
 #endif // SHARE_VM_CLASSFILE_SYSTEMDICTIONARYSHARED_HPP
diff --git a/hotspot/src/share/vm/classfile/verifier.cpp b/hotspot/src/share/vm/classfile/verifier.cpp
index 9923058b..eb267b83 100644
--- a/hotspot/src/share/vm/classfile/verifier.cpp
+++ b/hotspot/src/share/vm/classfile/verifier.cpp
@@ -561,7 +561,8 @@ void ClassVerifier::verify_class(TRAPS) {
 
   for (int index = 0; index < num_methods; index++) {
     // Check for recursive re-verification before each method.
-    if (was_recursively_verified())  return;
+    // in CDS Sharing state we still verify the code.
+    if (!UseAppCDS && was_recursively_verified())  return;
 
     Method* m = methods->at(index);
     if (m->is_native() || m->is_abstract() || m->is_overpass()) {
diff --git a/hotspot/src/share/vm/memory/filemap.cpp b/hotspot/src/share/vm/memory/filemap.cpp
index 17447587..d2095e63 100644
--- a/hotspot/src/share/vm/memory/filemap.cpp
+++ b/hotspot/src/share/vm/memory/filemap.cpp
@@ -22,6 +22,7 @@
  *
  */
 
+#include "jvm.h"
 #include "precompiled.hpp"
 #include "classfile/classLoader.hpp"
 #include "classfile/sharedClassUtil.hpp"
@@ -33,10 +34,13 @@
 #include "memory/oopFactory.hpp"
 #include "oops/objArrayOop.hpp"
 #include "runtime/arguments.hpp"
+#include "runtime/globals.hpp"
 #include "runtime/java.hpp"
 #include "runtime/os.hpp"
 #include "services/memTracker.hpp"
+#include "utilities/debug.hpp"
 #include "utilities/defaultStream.hpp"
+#include "utilities/ostream.hpp"
 
 # include <sys/stat.h>
 # include <errno.h>
@@ -362,11 +366,33 @@ bool FileMapInfo::open_for_read() {
   return true;
 }
 
-
 // Write the FileMapInfo information to the file.
-
 void FileMapInfo::open_for_write() {
- _full_path = make_log_name(Arguments::GetSharedArchivePath(), NULL);
+  if (UseAppCDS && AppCDSLockFile != NULL) {
+    char* pos = strrchr(const_cast<char*>(AppCDSLockFile), '/');
+    if (pos != NULL && pos != AppCDSLockFile) { // No directory path specified
+      char buf[PATH_MAX + 1] = "\0";
+      char filePath[PATH_MAX] = "\0";
+      int length = pos - AppCDSLockFile + 1;
+      strncpy(filePath, AppCDSLockFile, length);
+      if (realpath(filePath, buf) == NULL) {
+        fail_stop("A risky filePath:%s, buf:%s, length:%d", filePath, buf, length);
+      }
+      _appcds_file_lock_path = os::strdup(AppCDSLockFile, mtInternal);
+      if (_appcds_file_lock_path == NULL) {
+        fail_stop("Failed to create appcds file lock.");
+      }
+      int lock_fd = open(_appcds_file_lock_path, O_CREAT | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR);
+      if (lock_fd < 0) {
+        tty->print_cr("The lock path is: %s", _appcds_file_lock_path);
+        tty->print_cr("Failed to create jsa file !\n Please check: \n 1. The directory exists.\n "
+		      "2. You have the permission.\n 3. Make sure no other process using the same lock file.\n");
+        JVM_Halt(0);
+      }
+      tty->print_cr("You are using file lock %s in concurrent mode", AppCDSLockFile);
+    }
+  }
+  _full_path = make_log_name(Arguments::GetSharedArchivePath(), NULL);
   if (PrintSharedSpaces) {
     tty->print_cr("Dumping shared data to file: ");
     tty->print_cr("   %s", _full_path);
@@ -452,6 +478,7 @@ void FileMapInfo::write_bytes(const void* buffer, int nbytes) {
       // close and remove the file. See bug 6372906.
       close();
       remove(_full_path);
+      remove(_appcds_file_lock_path);
       fail_stop("Unable to write to shared archive file.");
     }
   }
@@ -492,6 +519,10 @@ void FileMapInfo::write_bytes_aligned(const void* buffer, int nbytes) {
 // Close the shared archive file.  This does NOT unmap mapped regions.
 
 void FileMapInfo::close() {
+  if (UseAppCDS && AppCDSLockFile != NULL) {
+    // delete appcds.lock
+    remove(_appcds_file_lock_path);
+  }
   if (_file_open) {
     if (::close(_fd) < 0) {
       fail_stop("Unable to close the shared archive file.");
diff --git a/hotspot/src/share/vm/memory/filemap.hpp b/hotspot/src/share/vm/memory/filemap.hpp
index acff6c9d..c09fbca1 100644
--- a/hotspot/src/share/vm/memory/filemap.hpp
+++ b/hotspot/src/share/vm/memory/filemap.hpp
@@ -143,6 +143,7 @@ public:
   FileMapHeader * _header;
 
   const char* _full_path;
+  const char* _appcds_file_lock_path;
   char* _paths_misc_info;
 
   static FileMapInfo* _current_info;
diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp
index 073c38ac..ebb5e114 100644
--- a/hotspot/src/share/vm/runtime/arguments.cpp
+++ b/hotspot/src/share/vm/runtime/arguments.cpp
@@ -36,6 +36,7 @@
 #include "prims/jvmtiExport.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/arguments_ext.hpp"
+#include "runtime/globals.hpp"
 #include "runtime/globals_extension.hpp"
 #include "runtime/java.hpp"
 #include "services/management.hpp"
@@ -1493,7 +1494,6 @@ void Arguments::set_use_compressed_oops() {
   // the only value that can override MaxHeapSize if we are
   // to use UseCompressedOops is InitialHeapSize.
   size_t max_heap_size = MAX2(MaxHeapSize, InitialHeapSize);
-
   if (max_heap_size <= max_heap_for_compressed_oops()) {
 #if !defined(COMPILER1) || defined(TIERED)
     if (FLAG_IS_DEFAULT(UseCompressedOops)) {
@@ -3023,9 +3023,6 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
       if (!process_argument("+UseAppCDS", args->ignoreUnrecognized, origin)) {
         return JNI_EINVAL;
       } else {
-        const char* n = "SharedArchiveFile";
-        Flag* shared_archive_flag = Flag::find_flag(n, strlen(n), true, true);
-        shared_archive_flag->unlock_diagnostic();
         FLAG_SET_CMDLINE(bool, UseAppCDS, true);
       }
     }
@@ -3382,6 +3379,9 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
     } else if (match_option(option, "-Xshare:off", &tail)) {
       FLAG_SET_CMDLINE(bool, UseSharedSpaces, false);
       FLAG_SET_CMDLINE(bool, RequireSharedSpaces, false);
+    // -Xtypecheck
+    } else if (match_option(option, "-Xtypecheck:on", &tail)) {
+      FLAG_SET_CMDLINE(bool, EnableSplitVerifierForAppCDS, true);
     // -Xverify
     } else if (match_option(option, "-Xverify", &tail)) {
       if (strcmp(tail, ":all") == 0 || strcmp(tail, "") == 0) {
@@ -3632,7 +3632,10 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
     FLAG_SET_CMDLINE(bool, RequireSharedSpaces, true);
     FLAG_SET_CMDLINE(bool, TraceClassPaths, true);
   }
-
+  if (DumpSharedSpaces && !UseAppCDS && AppCDSLockFile != NULL) {
+    jio_fprintf(defaultStream::error_stream(), "AppCDSLockFile is only used when AppCDS is enabled.");
+    return JNI_ERR;
+  }
   // Change the default value for flags  which have different default values
   // when working with older JDKs.
 #ifdef LINUX
@@ -4057,6 +4060,7 @@ static char* get_shared_archive_path() {
   return shared_archive_path;
 }
 
+
 #ifndef PRODUCT
 // Determine whether LogVMOutput should be implicitly turned on.
 static bool use_vm_log() {
@@ -4199,6 +4203,7 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
     return JNI_ENOMEM;
   }
 
+
   // Set up VerifySharedSpaces
   if (FLAG_IS_DEFAULT(VerifySharedSpaces) && SharedArchiveFile != NULL) {
     VerifySharedSpaces = true;
diff --git a/hotspot/src/share/vm/runtime/arguments.hpp b/hotspot/src/share/vm/runtime/arguments.hpp
index 6f7ff138..03f293e3 100644
--- a/hotspot/src/share/vm/runtime/arguments.hpp
+++ b/hotspot/src/share/vm/runtime/arguments.hpp
@@ -473,6 +473,7 @@ class Arguments : AllStatic {
   static bool   CheckCompileOnly;
 
   static char*  SharedArchivePath;
+  static char*  AppCDSLockPath;
 
  public:
   // Parses the arguments, first phase
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
index 65b11caa..b72efd45 100644
--- a/hotspot/src/share/vm/runtime/globals.hpp
+++ b/hotspot/src/share/vm/runtime/globals.hpp
@@ -4007,15 +4007,21 @@ class CommandLineFlags {
   product(ccstr, SharedClassListFile, NULL,                                 \
           "Override the default CDS class list")                            \
                                                                             \
-  diagnostic(ccstr, SharedArchiveFile, NULL,                                \
+  product(ccstr, SharedArchiveFile, NULL,                                   \
           "Override the default location of the CDS archive file")          \
                                                                             \
+  product(ccstr, AppCDSLockFile, NULL,                                      \
+          "Override the default location of the AppCDS lock file")          \
+                                                                            \
   product(ccstr, ExtraSharedClassListFile, NULL,                            \
           "Extra classlist for building the CDS archive file")              \
                                                                             \
   product(bool, UseAppCDS, false,                                           \
           "Enable Application Class Data Sharing (AppCDS)")                 \
                                                                             \
+  product(bool, EnableSplitVerifierForAppCDS, false,                        \
+          "Enable Type Check (AppCDS)")                                     \
+                                                                            \
   experimental(uintx, ArrayAllocatorMallocLimit,                            \
           SOLARIS_ONLY(64*K) NOT_SOLARIS(max_uintx),                        \
           "Allocation less than this value will be allocated "              \
diff --git a/hotspot/src/share/vm/utilities/ostream.cpp b/hotspot/src/share/vm/utilities/ostream.cpp
index 2b458fe4..587b839b 100644
--- a/hotspot/src/share/vm/utilities/ostream.cpp
+++ b/hotspot/src/share/vm/utilities/ostream.cpp
@@ -34,6 +34,9 @@
 #include "utilities/ostream.hpp"
 #include "utilities/top.hpp"
 #include "utilities/xmlstream.hpp"
+
+# include <sys/file.h>
+
 #ifdef TARGET_OS_FAMILY_linux
 # include "os_linux.inline.hpp"
 #endif
@@ -376,7 +379,7 @@ stringStream::~stringStream() {}
 xmlStream*   xtty;
 outputStream* tty;
 outputStream* gclog_or_tty;
-CDS_ONLY(fileStream* classlist_file;) // Only dump the classes that can be stored into the CDS archive
+CDS_ONLY(jsaFileStream* classlist_file;) // Only dump the classes that can be stored into the CDS archive
 extern Mutex* tty_lock;
 
 #define EXTRACHARLEN   32
@@ -760,6 +763,36 @@ void fileStream::flush() {
   fflush(_file);
 }
 
+jsaFileStream::jsaFileStream(const char* file_name) : fileStream(file_name, "a") {
+  if (_file != NULL) {
+    if (flock(fileno(_file), LOCK_EX | LOCK_NB) != 0) {
+      if (errno == EWOULDBLOCK) {
+        warning("file %s is locked by another process\n", file_name);
+      } else {
+        warning("Cannot lock file %s due to %s\n", file_name, strerror(errno));
+      }
+      fclose(_file);
+      _file = NULL;
+      _need_close = false;
+    } else {
+      if (::ftruncate(fileno(_file), 0) != 0) {
+          warning("Fail to ftruncate file %s due to %s\n", file_name, strerror(errno));
+      }
+      ::rewind(_file);
+    }
+  }
+}
+
+jsaFileStream::~jsaFileStream() {
+  // flock is released automatically when _file is closed
+  // Ensure the following sequnce in fclose
+  // 1. fflush. 2. flock(unlock); 3. close
+  if (_file != NULL) {
+    if (_need_close) fclose(_file);
+    _file      = NULL;
+  }
+}
+
 fdStream::fdStream(const char* file_name) {
   _fd = open(file_name, O_WRONLY | O_CREAT | O_TRUNC, 0666);
   _need_close = true;
@@ -1362,7 +1395,7 @@ void ostream_init_log() {
   if (DumpLoadedClassList != NULL) {
     const char* list_name = make_log_name(DumpLoadedClassList, NULL);
     classlist_file = new(ResourceObj::C_HEAP, mtInternal)
-                         fileStream(list_name);
+                         jsaFileStream(list_name);
     FREE_C_HEAP_ARRAY(char, list_name, mtInternal);
   }
 #endif
diff --git a/hotspot/src/share/vm/utilities/ostream.hpp b/hotspot/src/share/vm/utilities/ostream.hpp
index 530c523c..c69289fb 100644
--- a/hotspot/src/share/vm/utilities/ostream.hpp
+++ b/hotspot/src/share/vm/utilities/ostream.hpp
@@ -214,7 +214,13 @@ class fileStream : public outputStream {
   void flush();
 };
 
-CDS_ONLY(extern fileStream*   classlist_file;)
+class jsaFileStream : public fileStream {
+ public:
+  jsaFileStream(const char* file_name);
+  ~jsaFileStream();
+};
+
+CDS_ONLY(extern jsaFileStream*   classlist_file;)
 
 // unlike fileStream, fdStream does unbuffered I/O by calling
 // open() and write() directly. It is async-safe, but output
