diff a/src/hotspot/share/cds/archiveHeapWriter.cpp b/src/hotspot/share/cds/archiveHeapWriter.cpp
--- a/src/hotspot/share/cds/archiveHeapWriter.cpp
+++ b/src/hotspot/share/cds/archiveHeapWriter.cpp
@@ -25,10 +25,11 @@
 #include "precompiled.hpp"
 #include "cds/archiveHeapWriter.hpp"
 #include "cds/cdsConfig.hpp"
 #include "cds/filemap.hpp"
 #include "cds/heapShared.hpp"
+#include "cds/regeneratedClasses.hpp"
 #include "classfile/javaClasses.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "gc/shared/collectedHeap.hpp"
 #include "memory/iterator.inline.hpp"
 #include "memory/oopFactory.hpp"
@@ -58,10 +59,15 @@
 HeapRootSegments ArchiveHeapWriter::_heap_root_segments;
 
 address ArchiveHeapWriter::_requested_bottom;
 address ArchiveHeapWriter::_requested_top;
 
+static size_t _num_strings = 0;
+static size_t _string_bytes = 0; 
+static size_t _num_packages = 0;
+static size_t _num_protection_domains = 0;
+
 GrowableArrayCHeap<ArchiveHeapWriter::NativePointerInfo, mtClassShared>* ArchiveHeapWriter::_native_pointers;
 GrowableArrayCHeap<oop, mtClassShared>* ArchiveHeapWriter::_source_objs;
 GrowableArrayCHeap<ArchiveHeapWriter::HeapObjOrder, mtClassShared>* ArchiveHeapWriter::_source_objs_order;
 
 ArchiveHeapWriter::BufferOffsetToSourceObjectTable*
@@ -318,17 +324,22 @@
     oop src_obj = _source_objs->at(src_obj_index);
     HeapShared::CachedOopInfo* info = HeapShared::archived_object_cache()->get(src_obj);
     assert(info != nullptr, "must be");
     size_t buffer_offset = copy_one_source_obj_to_buffer(src_obj);
     info->set_buffer_offset(buffer_offset);
+    assert(buffer_offset <= 0x7fffffff, "sanity");
+    HeapShared::add_to_permanent_oop_table(src_obj, (int)buffer_offset);
 
     _buffer_offset_to_source_obj_table->put_when_absent(buffer_offset, src_obj);
     _buffer_offset_to_source_obj_table->maybe_grow();
   }
 
   log_info(cds)("Size of heap region = " SIZE_FORMAT " bytes, %d objects, %d roots, %d native ptrs",
                 _buffer_used, _source_objs->length() + 1, roots->length(), _num_native_ptrs);
+  log_info(cds)("   strings            = " SIZE_FORMAT_W(8) " (" SIZE_FORMAT " bytes)", _num_strings, _string_bytes);
+  log_info(cds)("   packages           = " SIZE_FORMAT_W(8), _num_packages);
+  log_info(cds)("   protection domains = " SIZE_FORMAT_W(8),_num_protection_domains);
 }
 
 size_t ArchiveHeapWriter::filler_array_byte_size(int length) {
   size_t byte_size = objArrayOopDesc::object_size(length) * HeapWordSize;
   return byte_size;
@@ -413,11 +424,29 @@
 void update_buffered_object_field(address buffered_obj, int field_offset, T value) {
   T* field_addr = cast_to_oop(buffered_obj)->field_addr<T>(field_offset);
   *field_addr = value;
 }
 
+void ArchiveHeapWriter::update_stats(oop src_obj) {
+  if (java_lang_String::is_instance(src_obj)) {
+    _num_strings ++;
+    _string_bytes += src_obj->size() * HeapWordSize;
+    _string_bytes += java_lang_String::value(src_obj)->size() * HeapWordSize;
+  } else {
+    Klass* k = src_obj->klass();
+    Symbol* name = k->name();
+    if (name->equals("java/lang/NamedPackage") || name->equals("java/lang/Package")) {
+      _num_packages ++;
+    } else if (name->equals("java/security/ProtectionDomain")) {
+      _num_protection_domains ++;
+    }
+  }
+}
+
 size_t ArchiveHeapWriter::copy_one_source_obj_to_buffer(oop src_obj) {
+  update_stats(src_obj);
+
   assert(!is_too_large_to_archive(src_obj), "already checked");
   size_t byte_size = src_obj->size() * HeapWordSize;
   assert(byte_size > 0, "no zero-size objects");
 
   // For region-based collectors such as G1, the archive heap may be mapped into
@@ -683,10 +712,23 @@
   if (ptr != nullptr) {
     NativePointerInfo info;
     info._src_obj = src_obj;
     info._field_offset = field_offset;
     _native_pointers->append(info);
+    if (!ArchiveBuilder::current()->has_been_archived((address)ptr)) {
+      // Currently we supporting marking of only Method and Klass, both of which are
+      // subtypes of MetaData.
+      ResourceMark rm;
+      log_error(cds, heap)("Native pointer %p is not archived", ptr);
+      if (((Metadata*)ptr)->is_method()) {
+        log_error(cds, heap)("Method: %s", ((Method*)ptr)->external_name());
+      } else {
+        assert(((Metadata*)ptr)->is_klass(), "must be");
+        log_error(cds, heap)("Klass: %s", ((Klass*)ptr)->external_name());
+      }
+      HeapShared::exit_on_error();
+    }
     HeapShared::set_has_native_pointers(src_obj);
     _num_native_ptrs ++;
   }
 }
 
@@ -741,10 +783,14 @@
     Metadata* native_ptr = *buffered_field_addr;
     guarantee(native_ptr != nullptr, "sanity");
     guarantee(ArchiveBuilder::current()->has_been_buffered((address)native_ptr),
               "Metadata %p should have been archived", native_ptr);
 
+    if (RegeneratedClasses::has_been_regenerated((address)native_ptr)) {
+      native_ptr = (Metadata*)RegeneratedClasses::get_regenerated_object((address)native_ptr);
+    }
+
     address buffered_native_ptr = ArchiveBuilder::current()->get_buffered_addr((address)native_ptr);
     address requested_native_ptr = ArchiveBuilder::current()->to_requested(buffered_native_ptr);
     *buffered_field_addr = (Metadata*)requested_native_ptr;
   }
 
