diff a/src/hotspot/share/cds/cppVtables.cpp b/src/hotspot/share/cds/cppVtables.cpp
--- a/src/hotspot/share/cds/cppVtables.cpp
+++ b/src/hotspot/share/cds/cppVtables.cpp
@@ -31,11 +31,13 @@
 #include "logging/log.hpp"
 #include "oops/instanceClassLoaderKlass.hpp"
 #include "oops/instanceMirrorKlass.hpp"
 #include "oops/instanceRefKlass.hpp"
 #include "oops/instanceStackChunkKlass.hpp"
+#include "oops/methodCounters.hpp"
 #include "oops/methodData.hpp"
+#include "oops/trainingData.hpp"
 #include "oops/objArrayKlass.hpp"
 #include "oops/typeArrayKlass.hpp"
 #include "runtime/arguments.hpp"
 #include "utilities/globalDefinitions.hpp"
 
@@ -59,12 +61,17 @@
   f(InstanceClassLoaderKlass) \
   f(InstanceMirrorKlass) \
   f(InstanceRefKlass) \
   f(InstanceStackChunkKlass) \
   f(Method) \
+  f(MethodData)                \
+  f(MethodCounters)            \
   f(ObjArrayKlass) \
-  f(TypeArrayKlass)
+  f(TypeArrayKlass)            \
+  f(KlassTrainingData)         \
+  f(MethodTrainingData)        \
+  f(CompileTrainingData)
 
 class CppVtableInfo {
   intptr_t _vtable_size;
   intptr_t _cloned_vtable[1]; // Pseudo flexible array member.
   static size_t cloned_vtable_offset() { return offset_of(CppVtableInfo, _cloned_vtable); }
@@ -192,11 +199,12 @@
 
 // This is a map of all the original vtptrs. E.g., for
 //     ConstantPool *cp = new (...) ConstantPool(...) ; // a dynamically allocated constant pool
 // the following holds true:
 //     _orig_cpp_vtptrs[ConstantPool_Kind] ==  ((intptr_t**)cp)[0]
-static intptr_t* _orig_cpp_vtptrs[_num_cloned_vtable_kinds];
+static intptr_t* _orig_cpp_vtptrs[_num_cloned_vtable_kinds];  // vtptrs set by the C++ compiler
+static intptr_t* _archived_cpp_vtptrs[_num_cloned_vtable_kinds];  // vtptrs used in the static archive
 static bool _orig_cpp_vtptrs_inited = false;
 
 template <class T>
 void CppVtableCloner<T>::init_orig_cpp_vtptr(int kind) {
   assert(kind < _num_cloned_vtable_kinds, "sanity");
@@ -222,10 +230,16 @@
 void CppVtables::dumptime_init(ArchiveBuilder* builder) {
   assert(CDSConfig::is_dumping_static_archive(), "cpp tables are only dumped into static archive");
 
   CPP_VTABLE_TYPES_DO(ALLOCATE_AND_INITIALIZE_VTABLE);
 
+  if (!CDSConfig::is_dumping_final_static_archive()) {
+    for (int kind = 0; kind < _num_cloned_vtable_kinds; kind++) {
+      _archived_cpp_vtptrs[kind] = _index[kind]->cloned_vtable();
+    }
+  }
+
   size_t cpp_tables_size = builder->rw_region()->top() - builder->rw_region()->base();
   builder->alloc_stats()->record_cpp_vtables((int)cpp_tables_size);
 }
 
 void CppVtables::serialize(SerializeClosure* soc) {
@@ -236,10 +250,18 @@
     soc->do_ptr(&_index[i]);
   }
   if (soc->reading()) {
     CPP_VTABLE_TYPES_DO(INITIALIZE_VTABLE);
   }
+
+  if (soc->writing() && CDSConfig::is_dumping_final_static_archive()) {
+    memset(_archived_cpp_vtptrs, 0, sizeof(_archived_cpp_vtptrs));
+  }
+
+  for (int kind = 0; kind < _num_cloned_vtable_kinds; kind++) {
+    soc->do_ptr(&_archived_cpp_vtptrs[kind]);
+  }
 }
 
 intptr_t* CppVtables::get_archived_vtable(MetaspaceObj::Type msotype, address obj) {
   if (!_orig_cpp_vtptrs_inited) {
     CPP_VTABLE_TYPES_DO(INIT_ORIG_CPP_VTPTRS);
@@ -256,22 +278,18 @@
   case MetaspaceObj::TypeArrayU8Type:
   case MetaspaceObj::TypeArrayOtherType:
   case MetaspaceObj::ConstMethodType:
   case MetaspaceObj::ConstantPoolCacheType:
   case MetaspaceObj::AnnotationsType:
-  case MetaspaceObj::MethodCountersType:
   case MetaspaceObj::SharedClassPathEntryType:
   case MetaspaceObj::RecordComponentType:
     // These have no vtables.
     break;
-  case MetaspaceObj::MethodDataType:
-    // We don't archive MethodData <-- should have been removed in removed_unsharable_info
-    ShouldNotReachHere();
-    break;
   default:
     for (kind = 0; kind < _num_cloned_vtable_kinds; kind ++) {
-      if (vtable_of((Metadata*)obj) == _orig_cpp_vtptrs[kind]) {
+      if (vtable_of((Metadata*)obj) == _orig_cpp_vtptrs[kind] ||
+          vtable_of((Metadata*)obj) == _archived_cpp_vtptrs[kind]) {
         break;
       }
     }
     if (kind >= _num_cloned_vtable_kinds) {
       fatal("Cannot find C++ vtable for " INTPTR_FORMAT " -- you probably added"
