diff a/src/hotspot/share/cds/cdsEnumKlass.cpp b/src/hotspot/share/cds/cdsEnumKlass.cpp
--- a/src/hotspot/share/cds/cdsEnumKlass.cpp
+++ b/src/hotspot/share/cds/cdsEnumKlass.cpp
@@ -40,32 +40,41 @@
   Klass* buffered_k = ArchiveBuilder::get_buffered_klass(k);
   return k->is_instance_klass() &&
          InstanceKlass::cast(k)->java_super() == vmClasses::Enum_klass();
 }
 
-// -- Handling of Enum objects
-// Java Enum classes have synthetic <clinit> methods that look like this
-//     enum MyEnum {FOO, BAR}
+// -- Archiving of Enum objects
+//
+// Parts of the <clinit> method of a Java enum is synthetically generated by javac. For example,
+//
+//  enum MyEnum {
+//      FOO, BAR;
+//      static final int BAZ = baz();
+// }
+//
+// Its <clinit> looks like this:
 //     MyEnum::<clinint> {
-//        /*static final MyEnum*/ MyEnum::FOO = new MyEnum("FOO");
-//        /*static final MyEnum*/ MyEnum::BAR = new MyEnum("BAR");
+//        static final MyEnum FOO = new MyEnum("FOO");   // generated by javac
+//        static final MyEnum BAR = new MyEnum("BAR");   // generated by javac
+//        static final MyEnum[] $VALUES = $values();     // generated by javac
+//        static final int BAZ = baz();                  // from source code. 
 //     }
 //
 // If MyEnum::FOO object is referenced by any of the archived subgraphs, we must
 // ensure the archived value equals (in object address) to the runtime value of
 // MyEnum::FOO.
 //
 // However, since MyEnum::<clinint> is synthetically generated by javac, there's
-// no way of programmatically handling this inside the Java code (as you would handle
+// no way to programmatically archive MuEnum::FOO inside the Java code (as you would handle
 // ModuleLayer::EMPTY_LAYER, for example).
 //
 // Instead, we archive all static field of such Enum classes. At runtime,
 // HeapShared::initialize_enum_klass() skips the <clinit> method and instead pulls
 // the static fields out of the archived heap.
-void CDSEnumKlass::handle_enum_obj(int level,
-                                   KlassSubGraphInfo* subgraph_info,
-                                   oop orig_obj) {
+void CDSEnumKlass::archive_enum_obj(int level,
+                                    KlassSubGraphInfo* subgraph_info,
+                                    oop orig_obj) {
   assert(level > 1, "must never be called at the first (outermost) level");
   assert(is_enum_obj(orig_obj), "must be");
 
   InstanceKlass* ik = InstanceKlass::cast(orig_obj->klass());
   if (ik->has_archived_enum_objs()) {
@@ -76,28 +85,53 @@
   ArchiveBuilder::get_buffered_klass(ik)->set_has_archived_enum_objs();
 
   oop mirror = ik->java_mirror();
   for (JavaFieldStream fs(ik); !fs.done(); fs.next()) {
     if (fs.access_flags().is_static()) {
-      archive_static_field(level, subgraph_info, ik, mirror, fs);
+      fieldDescriptor& fd = fs.field_descriptor();
+      if (fd.field_type() == T_OBJECT || fd.field_type() == T_ARRAY) {
+        archive_static_oop_field(level, subgraph_info, ik, mirror, fd);
+      } else {
+        archive_static_primitive_field(level, subgraph_info, ik, mirror, fd);
+      }
     }
   }
 }
 
-void CDSEnumKlass::archive_static_field(int level, KlassSubGraphInfo* subgraph_info,
-                                        InstanceKlass* ik, oop mirror, JavaFieldStream& fs) {
-  ResourceMark rm;
-  fieldDescriptor& fd = fs.field_descriptor();
-  if (fd.field_type() != T_OBJECT && fd.field_type() != T_ARRAY) {
-    guarantee(false, "static field %s::%s must be T_OBJECT or T_ARRAY",
-              ik->external_name(), fd.name()->as_C_string());
+bool CDSEnumKlass::can_archive_static_oop_field(InstanceKlass* enum_klass, oop obj) {
+  Klass* klass = obj->klass();
+  if ( klass == enum_klass || klass == enum_klass->array_klass_or_null()) {
+    // These two types of fields are generated by javac for enum classes
+    return true;
   }
+
+  // Special handling for the sun.invoke.util.Wrapper enum. We need this in order
+  // to archive instances of java.lang.invoke.MethodTypes.
+  if (klass == vmClasses::Boolean_klass() ||
+      klass == vmClasses::Byte_klass() ||
+      klass == vmClasses::Character_klass() ||
+      klass == vmClasses::Short_klass() ||
+      klass == vmClasses::Integer_klass() ||
+      klass == vmClasses::Long_klass() ||
+      klass == vmClasses::Float_klass() ||
+      klass == vmClasses::Double_klass() ||
+      klass == vmClasses::Void_klass()) {
+    return true;
+  }
+
+  return false;
+}
+
+void CDSEnumKlass::archive_static_oop_field(int level, KlassSubGraphInfo* subgraph_info,
+                                            InstanceKlass* ik, oop mirror, fieldDescriptor& fd) {
+  ResourceMark rm;
   oop oop_field = mirror->obj_field(fd.offset());
   if (oop_field == nullptr) {
-    guarantee(false, "static field %s::%s must not be null",
-              ik->external_name(), fd.name()->as_C_string());
-  } else if (oop_field->klass() != ik && oop_field->klass() != ik->array_klass_or_null()) {
+    return;
+  }
+
+  if (!can_archive_static_oop_field(ik, oop_field)) {
     guarantee(false, "static field %s::%s is of the wrong type",
               ik->external_name(), fd.name()->as_C_string());
   }
   bool success = HeapShared::archive_reachable_objects_from(level, subgraph_info, oop_field);
   assert(success, "VM should have exited with unarchivable objects for _level > 1");
@@ -106,10 +140,65 @@
                       root_index, ik->external_name(), fd.name()->as_C_string(),
                       p2i((oopDesc*)oop_field));
   SystemDictionaryShared::add_enum_klass_static_field(ik, root_index);
 }
 
+
+void CDSEnumKlass::archive_static_primitive_field(int level, KlassSubGraphInfo* subgraph_info,
+                                                  InstanceKlass* ik, oop mirror, fieldDescriptor& fd) {
+  int v;
+  switch (fd.field_type()) {
+  case T_BOOLEAN:
+    v = mirror->bool_field(fd.offset());
+    SystemDictionaryShared::add_enum_klass_static_field(ik, v);
+    break;
+  case T_BYTE:
+    v = mirror->byte_field(fd.offset());
+    SystemDictionaryShared::add_enum_klass_static_field(ik, v);
+    break;
+  case T_SHORT:
+    v = mirror->short_field(fd.offset());
+    SystemDictionaryShared::add_enum_klass_static_field(ik, v);
+    break;
+  case T_CHAR:
+    v = mirror->char_field(fd.offset());
+    SystemDictionaryShared::add_enum_klass_static_field(ik, v);
+    break;
+  case T_INT:
+    v = mirror->int_field(fd.offset());
+    SystemDictionaryShared::add_enum_klass_static_field(ik, v);
+    break;
+  case T_LONG:
+    {
+      jlong value = mirror->long_field(fd.offset());
+      v = value & 0xffffffff;
+      SystemDictionaryShared::add_enum_klass_static_field(ik, v);
+      v = value > 32;
+      SystemDictionaryShared::add_enum_klass_static_field(ik, v);
+    }
+    break;
+  case T_FLOAT:
+    {            
+      jfloat value = mirror->float_field(fd.offset());
+      int* p = (int*)(&value);
+      SystemDictionaryShared::add_enum_klass_static_field(ik, *p);
+    }
+    break;
+  case T_DOUBLE:
+    {
+      jdouble value = mirror->double_field(fd.offset());
+      int* p = (int*)(&value);
+      SystemDictionaryShared::add_enum_klass_static_field(ik, p[0]);
+      SystemDictionaryShared::add_enum_klass_static_field(ik, p[1]);
+    }
+    break;
+  default:
+    ShouldNotReachHere();
+  }
+}
+
+
 bool CDSEnumKlass::initialize_enum_klass(InstanceKlass* k, TRAPS) {
   if (!ArchiveHeapLoader::is_in_use()) {
     return false;
   }
 
@@ -123,14 +212,60 @@
 
   oop mirror = k->java_mirror();
   int i = 0;
   for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
     if (fs.access_flags().is_static()) {
-      int root_index = info->enum_klass_static_field_root_index_at(i++);
+      int v = info->enum_klass_static_field_root_index_at(i++);
       fieldDescriptor& fd = fs.field_descriptor();
-      assert(fd.field_type() == T_OBJECT || fd.field_type() == T_ARRAY, "must be");
-      mirror->obj_field_put(fd.offset(), HeapShared::get_root(root_index, /*clear=*/true));
+      switch (fd.field_type()) {
+      case T_OBJECT:
+      case T_ARRAY:
+        mirror->obj_field_put(fd.offset(), HeapShared::get_root(v, /*clear=*/true));
+        break;
+      case T_BOOLEAN:
+        mirror->bool_field_put(fd.offset(), v ? true : false);
+        break;
+      case T_BYTE:
+        mirror->byte_field_put(fd.offset(), (jbyte)v);
+        break;
+      case T_SHORT:
+        mirror->short_field_put(fd.offset(), (jshort)v);
+        break;
+      case T_CHAR:
+        mirror->char_field_put(fd.offset(), (jchar)v);
+        break;
+      case T_INT:
+        mirror->int_field_put(fd.offset(), v);
+        break;
+      case T_LONG:
+        {
+          int v2 = info->enum_klass_static_field_root_index_at(i++);
+          jlong lv = v2;
+          lv <<= 32;
+          lv += v;
+          mirror->long_field_put(fd.offset(), lv);
+        }
+        break;
+      case T_FLOAT:
+        {            
+          jfloat* p = (float*)&v;
+          mirror->float_field_put(fd.offset(), *p);
+        }
+        break;
+      case T_DOUBLE:
+        {
+          int v2 = info->enum_klass_static_field_root_index_at(i++);
+          jdouble d = 0;
+          int* p = (int*)(&d);
+          p[0] = v;
+          p[1] = v2;
+          mirror->double_field_put(fd.offset(), d);
+        }
+        break;
+      default:
+        ShouldNotReachHere();
+      }
     }
   }
   return true;
 }
 #endif // INCLUDE_CDS_JAVA_HEAP
