diff a/src/hotspot/share/oops/constantPool.cpp b/src/hotspot/share/oops/constantPool.cpp
--- a/src/hotspot/share/oops/constantPool.cpp
+++ b/src/hotspot/share/oops/constantPool.cpp
@@ -26,16 +26,19 @@
 #include "cds/archiveHeapWriter.hpp"
 #include "cds/archiveHeapLoader.hpp"
 #include "cds/archiveBuilder.hpp"
 #include "cds/cdsConfig.hpp"
 #include "cds/classPrelinker.hpp"
+#include "cds/lambdaFormInvokers.inline.hpp"
 #include "cds/heapShared.hpp"
+#include "classfile/classLoader.hpp"
 #include "classfile/classLoaderData.hpp"
 #include "classfile/javaClasses.inline.hpp"
 #include "classfile/metadataOnStackMark.hpp"
 #include "classfile/stringTable.hpp"
 #include "classfile/systemDictionary.hpp"
+#include "classfile/systemDictionaryShared.hpp"
 #include "classfile/vmClasses.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "code/codeCache.hpp"
 #include "interpreter/bootstrapInfo.hpp"
 #include "interpreter/linkResolver.hpp"
@@ -57,14 +60,16 @@
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/typeArrayOop.inline.hpp"
 #include "prims/jvmtiExport.hpp"
 #include "runtime/atomic.hpp"
+//#include "runtime/fieldDescriptor.inline.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/init.hpp"
 #include "runtime/javaCalls.hpp"
-#include "runtime/javaThread.hpp"
+#include "runtime/javaThread.inline.hpp"
+#include "runtime/perfData.hpp"
 #include "runtime/signature.hpp"
 #include "runtime/vframe.inline.hpp"
 #include "utilities/checkedCast.hpp"
 #include "utilities/copy.hpp"
 
@@ -296,25 +301,57 @@
     return nullptr;
   }
 
   objArrayOop rr = resolved_references();
   if (rr != nullptr) {
-    ConstantPool* orig_pool = ArchiveBuilder::current()->get_source_addr(this);
-    objArrayOop scratch_rr = HeapShared::scratch_resolved_references(orig_pool);
+    ResourceMark rm;
+    int rr_len = rr->length();
+    GrowableArray<bool> keep_resolved_refs(rr_len, rr_len, false);
+    ConstantPool* src_cp = ArchiveBuilder::current()->get_source_addr(this);
+
+    if (cache() != nullptr && ArchiveInvokeDynamic) {
+      Array<ResolvedIndyEntry>* indy_entries = cache()->resolved_indy_entries();
+      if (indy_entries != nullptr) {
+        for (int i = 0; i < indy_entries->length(); i++) {
+          ResolvedIndyEntry *rie = indy_entries->adr_at(i);
+          if (rie->is_resolved() && ClassPrelinker::is_resolution_deterministic(src_cp, rie->constant_pool_index())) {
+            int rr_index = rie->resolved_references_index();
+            keep_resolved_refs.at_put(rr_index, true);
+          }
+        }
+      }
+
+      Array<ResolvedMethodEntry>* method_entries = cache()->resolved_method_entries();
+      if (method_entries != nullptr) {
+        for (int i = 0; i < method_entries->length(); i++) {
+          ResolvedMethodEntry* rme = method_entries->adr_at(i);
+          if (rme->is_resolved(Bytecodes::_invokehandle) && rme->has_appendix() &&
+              can_archive_resolved_method(rme)) {
+            int rr_index = rme->resolved_references_index();
+            keep_resolved_refs.at_put(rr_index, true);
+          }
+        }
+      }
+    }
+
+    objArrayOop scratch_rr = HeapShared::scratch_resolved_references(src_cp);
     Array<u2>* ref_map = reference_map();
     int ref_map_len = ref_map == nullptr ? 0 : ref_map->length();
-    int rr_len = rr->length();
     for (int i = 0; i < rr_len; i++) {
       oop obj = rr->obj_at(i);
       scratch_rr->obj_at_put(i, nullptr);
-      if (obj != nullptr && i < ref_map_len) {
-        int index = object_to_cp_index(i);
-        if (tag_at(index).is_string()) {
-          assert(java_lang_String::is_instance(obj), "must be");
-          if (!ArchiveHeapWriter::is_string_too_large_to_archive(obj)) {
-            scratch_rr->obj_at_put(i, obj);
+      if (obj != nullptr) {
+        if (i < ref_map_len) {
+          int index = object_to_cp_index(i);
+          if (tag_at(index).is_string()) {
+            assert(java_lang_String::is_instance(obj), "must be");
+            if (!ArchiveHeapWriter::is_string_too_large_to_archive(obj)) {
+              scratch_rr->obj_at_put(i, obj);
+            }
           }
+        } else if (keep_resolved_refs.at(i)) {
+          scratch_rr->obj_at_put(i, obj);
         }
       }
     }
     return scratch_rr;
   }
@@ -343,10 +380,13 @@
     return;
   }
   assert(is_constantPool(), "ensure C++ vtable is restored");
   assert(on_stack(), "should always be set for shared constant pools");
   assert(is_shared(), "should always be set for shared constant pools");
+  if (is_for_method_handle_intrinsic()) {
+    return;
+  }
   assert(_cache != nullptr, "constant pool _cache should not be null");
 
   // Only create the new resolved references array if it hasn't been attempted before
   if (resolved_references() != nullptr) return;
 
@@ -373,36 +413,93 @@
         Handle refs_handle(THREAD, stom);  // must handleize.
         set_resolved_references(loader_data->add_handle(refs_handle));
       }
     }
   }
+
+  if (CDSConfig::is_dumping_final_static_archive() && resolved_references() != nullptr) {
+    objArrayOop scratch_references = oopFactory::new_objArray(vmClasses::Object_klass(), resolved_references()->length(), CHECK);
+    HeapShared::add_scratch_resolved_references(this, scratch_references);
+  }
 }
 
 void ConstantPool::remove_unshareable_info() {
   // Shared ConstantPools are in the RO region, so the _flags cannot be modified.
   // The _on_stack flag is used to prevent ConstantPools from deallocation during
   // class redefinition. Since shared ConstantPools cannot be deallocated anyway,
   // we always set _on_stack to true to avoid having to change _flags during runtime.
   _flags |= (_on_stack | _is_shared);
 
-  if (!_pool_holder->is_linked() && !_pool_holder->verified_at_dump_time()) {
+  if (!ArchiveBuilder::current()->get_source_addr(_pool_holder)->is_linked()) {
+    return;
+  }
+
+  if (is_for_method_handle_intrinsic()) {
+    // This CP was created by Method::make_method_handle_intrinsic() and has nothing
+    // that need to be removed/restored. It has no cpCache since the intrinsic methods
+    // don't have any bytecodes.
+    assert(cache() == NULL, "must not have cpCache");
     return;
   }
+
   // Resolved references are not in the shared archive.
   // Save the length for restoration.  It is not necessarily the same length
   // as reference_map.length() if invokedynamic is saved. It is needed when
   // re-creating the resolved reference array if archived heap data cannot be map
   // at runtime.
   set_resolved_reference_length(
     resolved_references() != nullptr ? resolved_references()->length() : 0);
   set_resolved_references(OopHandle());
 
-  bool archived = false;
+  remove_unshareable_entries();
+}
+
+static const char* get_type(Klass* k) {
+  const char* type;
+  Klass* src_k;
+  if (ArchiveBuilder::is_active() && ArchiveBuilder::current()->is_in_buffer_space(k)) {
+    src_k = ArchiveBuilder::current()->get_source_addr(k);
+  } else {
+    src_k = k;
+  }
+
+  if (src_k->is_objArray_klass()) {
+    src_k = ObjArrayKlass::cast(src_k)->bottom_klass();
+    assert(!src_k->is_objArray_klass(), "sanity");
+  }
+
+  if (src_k->is_typeArray_klass()) {
+    type = "prim";
+  } else {
+    InstanceKlass* src_ik = InstanceKlass::cast(src_k);
+    oop loader = src_ik->class_loader();
+    if (loader == nullptr) {
+      type = "boot";
+    } else if (loader == SystemDictionary::java_platform_loader()) {
+      type = "plat";
+    } else if (loader == SystemDictionary::java_system_loader()) {
+      type = "app";
+    } else {
+      type = "unreg";
+    }
+  }
+
+  return type;
+}
+
+void ConstantPool::remove_unshareable_entries() {
+  ResourceMark rm;
+  log_info(cds, resolve)("Archiving CP entries for %s", pool_holder()->name()->as_C_string());
   for (int cp_index = 1; cp_index < length(); cp_index++) { // cp_index 0 is unused
-    switch (tag_at(cp_index).value()) {
+    int cp_tag = tag_at(cp_index).value();
+    switch (cp_tag) {
+    case JVM_CONSTANT_UnresolvedClass:
+      ArchiveBuilder::alloc_stats()->record_klass_cp_entry(false);
+      break;
     case JVM_CONSTANT_UnresolvedClassInError:
       tag_at_put(cp_index, JVM_CONSTANT_UnresolvedClass);
+      ArchiveBuilder::alloc_stats()->record_klass_cp_entry(false);
       break;
     case JVM_CONSTANT_MethodHandleInError:
       tag_at_put(cp_index, JVM_CONSTANT_MethodHandle);
       break;
     case JVM_CONSTANT_MethodTypeInError:
@@ -410,56 +507,248 @@
       break;
     case JVM_CONSTANT_DynamicInError:
       tag_at_put(cp_index, JVM_CONSTANT_Dynamic);
       break;
     case JVM_CONSTANT_Class:
-      archived = maybe_archive_resolved_klass_at(cp_index);
-      ArchiveBuilder::alloc_stats()->record_klass_cp_entry(archived);
+      remove_resolved_klass_if_non_deterministic(cp_index);
+      break;
+    default:
       break;
     }
   }
 
   if (cache() != nullptr) {
     // cache() is null if this class is not yet linked.
-    cache()->remove_unshareable_info();
+    remove_resolved_field_entries_if_non_deterministic();
+    remove_resolved_method_entries_if_non_deterministic();
+    remove_resolved_indy_entries_if_non_deterministic();
   }
 }
 
-bool ConstantPool::maybe_archive_resolved_klass_at(int cp_index) {
+void ConstantPool::remove_resolved_klass_if_non_deterministic(int cp_index) {
   assert(ArchiveBuilder::current()->is_in_buffer_space(this), "must be");
   assert(tag_at(cp_index).is_klass(), "must be resolved");
 
-  if (pool_holder()->is_hidden() && cp_index == pool_holder()->this_class_index()) {
-    // All references to a hidden class's own field/methods are through this
-    // index, which was resolved in ClassFileParser::fill_instance_klass. We
-    // must preserve it.
-    return true;
-  }
-
-  CPKlassSlot kslot = klass_slot_at(cp_index);
-  int resolved_klass_index = kslot.resolved_klass_index();
-  Klass* k = resolved_klasses()->at(resolved_klass_index);
   // k could be null if the referenced class has been excluded via
   // SystemDictionaryShared::is_excluded_class().
-
+  Klass* k = resolved_klass_at(cp_index);
+  bool revert = true;
   if (k != nullptr) {
     ConstantPool* src_cp = ArchiveBuilder::current()->get_source_addr(this);
-    if (ClassPrelinker::can_archive_resolved_klass(src_cp, cp_index)) {
-      if (log_is_enabled(Debug, cds, resolve)) {
-        ResourceMark rm;
-        log_debug(cds, resolve)("Resolved klass CP entry [%d]: %s => %s", cp_index,
-                                pool_holder()->external_name(), k->external_name());
+    if (ClassPrelinker::is_resolution_deterministic(src_cp, cp_index)) {
+      revert = false;
+    }
+  }
+
+  if (revert) {
+    // This resolved klass entry cannot be archived. Revert the tag to UnresolvedClass,
+    // so that it will be resolved at runtime.
+    int resolved_klass_index = klass_slot_at(cp_index).resolved_klass_index();
+    resolved_klasses()->at_put(resolved_klass_index, nullptr);
+    tag_at_put(cp_index, JVM_CONSTANT_UnresolvedClass);
+  }
+
+  LogStreamHandle(Trace, cds, resolve) log;
+  if (log.is_enabled()) {
+    ResourceMark rm;
+    log.print("%s klass  CP entry [%3d]: %s %s",
+              (revert ? "reverted" : "archived"),
+              cp_index, pool_holder()->name()->as_C_string(), get_type(pool_holder()));
+    if (revert) {
+      Symbol* name = klass_name_at(cp_index);
+      log.print("  \"%s\"", name->as_C_string());
+    } else {
+      log.print(" => %s %s%s", k->name()->as_C_string(), get_type(k),
+                (!k->is_instance_klass() || pool_holder()->is_subtype_of(k)) ? "" : " (not supertype)");
+    }
+  }
+  ArchiveBuilder::alloc_stats()->record_klass_cp_entry(!revert);
+}
+
+void ConstantPool::remove_resolved_field_entries_if_non_deterministic() {
+  ConstantPool* src_cp =  ArchiveBuilder::current()->get_source_addr(this);
+  Array<ResolvedFieldEntry>* field_entries = cache()->resolved_field_entries();
+  if (field_entries != nullptr) {
+    for (int i = 0; i < field_entries->length(); i++) {
+      ResolvedFieldEntry* rfi = field_entries->adr_at(i);
+      int cp_index = rfi->constant_pool_index();
+      bool archived = false;
+      bool resolved = rfi->is_resolved(Bytecodes::_getstatic) ||
+                      rfi->is_resolved(Bytecodes::_putstatic) ||
+                      rfi->is_resolved(Bytecodes::_putfield)  ||
+                      rfi->is_resolved(Bytecodes::_putfield);
+      if (resolved && ClassPrelinker::is_resolution_deterministic(src_cp, cp_index)) {
+        rfi->mark_and_relocate();
+        archived = true;
+      } else {
+        rfi->remove_unshareable_info();
+      }
+      if (resolved) {
+        LogStreamHandle(Trace, cds, resolve) log;
+        if (log.is_enabled()) {
+          ResourceMark rm;
+          int klass_cp_index = uncached_klass_ref_index_at(cp_index);
+          Symbol* klass_name = klass_name_at(klass_cp_index);
+          Symbol* name = uncached_name_ref_at(cp_index);
+          Symbol* signature = uncached_signature_ref_at(cp_index);
+          log.print("%s field  CP entry [%3d]: %s %s %s.%s:%s",
+                    (archived ? "archived" : "excluded"),
+                    cp_index,
+                    pool_holder()->name()->as_C_string(),
+                    (archived ? "=>" : "  "),
+                    klass_name->as_C_string(), name->as_C_string(), signature->as_C_string());
+        }
+      }
+      ArchiveBuilder::alloc_stats()->record_field_cp_entry(archived, resolved && !archived);
+    }
+  }
+}
+
+void ConstantPool::remove_resolved_method_entries_if_non_deterministic() {
+  ConstantPool* src_cp =  ArchiveBuilder::current()->get_source_addr(this);
+  Array<ResolvedMethodEntry>* method_entries = cache()->resolved_method_entries();
+  if (method_entries != nullptr) {
+    for (int i = 0; i < method_entries->length(); i++) {
+      ResolvedMethodEntry* rme = method_entries->adr_at(i);
+      int cp_index = rme->constant_pool_index();
+      bool archived = false;
+      bool resolved = rme->is_resolved(Bytecodes::_invokevirtual)   ||
+                      rme->is_resolved(Bytecodes::_invokespecial)   ||
+                      rme->is_resolved(Bytecodes::_invokestatic)    ||
+                      rme->is_resolved(Bytecodes::_invokeinterface) ||
+                      rme->is_resolved(Bytecodes::_invokehandle);
+      if (resolved && can_archive_resolved_method(rme)) {
+        rme->mark_and_relocate(src_cp);
+        archived = true;
+      } else {
+        rme->remove_unshareable_info();
+      }
+      if (resolved) {
+        LogStreamHandle(Trace, cds, resolve) log;
+        if (log.is_enabled()) {
+          ResourceMark rm;
+          int klass_cp_index = uncached_klass_ref_index_at(cp_index);
+          Symbol* klass_name = klass_name_at(klass_cp_index);
+          Symbol* name = uncached_name_ref_at(cp_index);
+          Symbol* signature = uncached_signature_ref_at(cp_index);
+          log.print("%s%s method CP entry [%3d]: %s %s.%s:%s",
+                    (archived ? "archived" : "excluded"),
+                    (rme->is_resolved(Bytecodes::_invokeinterface) ? " interface" : ""),
+                    cp_index,
+                    pool_holder()->name()->as_C_string(),
+                    klass_name->as_C_string(), name->as_C_string(), signature->as_C_string());
+          if (archived) {
+            Klass* resolved_klass = resolved_klass_at(klass_cp_index);
+            log.print(" => %s%s",
+                      resolved_klass->name()->as_C_string(),
+                      (rme->is_resolved(Bytecodes::_invokestatic) ? " *** static" : ""));
+          }
+        }
       }
-      return true;
+      ArchiveBuilder::alloc_stats()->record_method_cp_entry(archived, resolved && !archived);
+    }
+  }
+}
+
+void ConstantPool::remove_resolved_indy_entries_if_non_deterministic() {
+  ConstantPool* src_cp =  ArchiveBuilder::current()->get_source_addr(this);
+  Array<ResolvedIndyEntry>* indy_entries = cache()->resolved_indy_entries();
+  if (indy_entries != nullptr) {
+    for (int i = 0; i < indy_entries->length(); i++) {
+      ResolvedIndyEntry* rei = indy_entries->adr_at(i);
+      int cp_index = rei->constant_pool_index();
+      bool archived = false;
+      bool resolved = rei->is_resolved();
+      if (resolved && ClassPrelinker::is_resolution_deterministic(src_cp, cp_index)) {
+        rei->mark_and_relocate();
+        archived = true;
+      } else {
+        rei->remove_unshareable_info();
+      }
+      if (resolved) {
+        LogStreamHandle(Trace, cds, resolve) log;
+        if (log.is_enabled()) {
+          ResourceMark rm;
+          int bsm = bootstrap_method_ref_index_at(cp_index);
+          int bsm_ref = method_handle_index_at(bsm);
+          Symbol* bsm_name = uncached_name_ref_at(bsm_ref);
+          Symbol* bsm_signature = uncached_signature_ref_at(bsm_ref);
+          Symbol* bsm_klass = klass_name_at(uncached_klass_ref_index_at(bsm_ref));
+          log.print("%s indy   CP entry [%3d]: %s (%d)",
+                    (archived ? "archived" : "excluded"),
+                    cp_index, pool_holder()->name()->as_C_string(), i);
+          log.print(" %s %s.%s:%s", (archived ? "=>" : "  "), bsm_klass->as_C_string(), bsm_name->as_C_string(), bsm_signature->as_C_string());
+        }
+      }
+      ArchiveBuilder::alloc_stats()->record_indy_cp_entry(archived, resolved && !archived);
+    }
+  }
+}
+
+bool ConstantPool::can_archive_invokehandle(ResolvedMethodEntry* rme) {
+  assert(rme->is_resolved(Bytecodes::_invokehandle), "sanity");
+
+  int cp_index = rme->constant_pool_index();
+  int klass_cp_index = uncached_klass_ref_index_at(cp_index);
+  Klass* resolved_klass = resolved_klass_at(klass_cp_index);
+  if (!resolved_klass->is_instance_klass()) {
+    // FIXME: can this ever happen?
+    return false;
+  }
+  // FIXME -- any class referenced by the archived CP entries should be added to ArchiveBuilder::classes, or should be
+  // filtered out.
+  return true;
+}
+
+bool ConstantPool::can_archive_resolved_method(ResolvedMethodEntry* method_entry) {
+  if (!(pool_holder()->is_shared_boot_class() || pool_holder()->is_shared_platform_class() ||
+        pool_holder()->is_shared_app_class())) {
+    // Archiving resolved cp entries for classes from non-builtin loaders
+    // is not yet supported.
+    return false;
+  }
+
+  if (CDSConfig::is_dumping_dynamic_archive()) {
+    // InstanceKlass::methods() is has been resorted. We need to
+    // update the vtable_index in method_entry (not implemented)
+    return false;
+  }
+
+  if (!method_entry->is_resolved(Bytecodes::_invokevirtual)) {
+    if (method_entry->method() == nullptr) {
+      return false;
+    }
+    if (method_entry->method()->is_continuation_native_intrinsic()) {
+      return false; // FIXME: corresponding stub is generated on demand during method resolution (see LinkResolver::resolve_static_call).
+    }
+  }
+
+  int cp_index = method_entry->constant_pool_index();
+  ConstantPool* src_cp = ArchiveBuilder::current()->get_source_addr(this);
+  assert(src_cp->tag_at(cp_index).is_method() || src_cp->tag_at(cp_index).is_interface_method(), "sanity");
+
+  if (!ClassPrelinker::is_resolution_deterministic(src_cp, cp_index)) {
+    return false;
+  }
+
+  if (method_entry->is_resolved(Bytecodes::_invokehandle)) {
+    if (!ArchiveInvokeDynamic) {
+      // invokehandle depends on archived MethodType and LambdaForms.
+      return false;
+    } else if (!can_archive_invokehandle(method_entry)) {
+      return false;
     }
+  } else if (method_entry->is_resolved(Bytecodes::_invokestatic) ||
+             method_entry->is_resolved(Bytecodes::_invokeinterface) ||
+             method_entry->is_resolved(Bytecodes::_invokevirtual) ||
+             method_entry->is_resolved(Bytecodes::_invokespecial)) {
+    // OK
+  } else {
+    return false; // just to be safe.
   }
 
-  // This referenced class cannot be archived. Revert the tag to UnresolvedClass,
-  // so that the proper class loading and initialization can happen at runtime.
-  resolved_klasses()->at_put(resolved_klass_index, nullptr);
-  tag_at_put(cp_index, JVM_CONSTANT_UnresolvedClass);
-  return false;
+  return true;
 }
 #endif // INCLUDE_CDS
 
 int ConstantPool::cp_to_object_index(int cp_index) {
   // this is harder don't do this so much.
@@ -697,13 +986,36 @@
     case Bytecodes::_invokestatic:
     case Bytecodes::_invokevirtual:
     case Bytecodes::_fast_invokevfinal: // Bytecode interpreter uses this
       return resolved_method_entry_at(index)->constant_pool_index();
     default:
-      tty->print_cr("Unexpected bytecode: %d", code);
-      ShouldNotReachHere(); // All cases should have been handled
-      return -1;
+      fatal("Unexpected bytecode: %s", Bytecodes::name(code));
+  }
+}
+
+bool ConstantPool::is_resolved(int index, Bytecodes::Code code) {
+  assert(cache() != nullptr, "'index' is a rewritten index so this class must have been rewritten");
+  switch(code) {
+    case Bytecodes::_invokedynamic:
+      return resolved_indy_entry_at(index)->is_resolved();
+
+    case Bytecodes::_getfield:
+    case Bytecodes::_getstatic:
+    case Bytecodes::_putfield:
+    case Bytecodes::_putstatic:
+      return resolved_field_entry_at(index)->is_resolved(code);
+
+    case Bytecodes::_invokeinterface:
+    case Bytecodes::_invokehandle:
+    case Bytecodes::_invokespecial:
+    case Bytecodes::_invokestatic:
+    case Bytecodes::_invokevirtual:
+    case Bytecodes::_fast_invokevfinal: // Bytecode interpreter uses this
+      return resolved_method_entry_at(index)->is_resolved(code);
+
+    default:
+      fatal("Unexpected bytecode: %s", Bytecodes::name(code));
   }
 }
 
 u2 ConstantPool::uncached_name_and_type_ref_index_at(int cp_index)  {
   if (tag_at(cp_index).has_bootstrap()) {
@@ -1012,11 +1324,13 @@
       result_oop = resolved->java_mirror();
       break;
     }
 
   case JVM_CONSTANT_Dynamic:
-    {
+    { PerfTraceTimedEvent timer(ClassLoader::perf_resolve_invokedynamic_time(),
+                                ClassLoader::perf_resolve_invokedynamic_count(),
+                                THREAD->class_being_initialized() == nullptr);
       // Resolve the Dynamically-Computed constant to invoke the BSM in order to obtain the resulting oop.
       BootstrapInfo bootstrap_specifier(this_cp, cp_index);
 
       // The initial step in resolving an unresolved symbolic reference to a
       // dynamically-computed constant is to resolve the symbolic reference to a
@@ -1070,11 +1384,13 @@
     assert(cache_index != _no_index_sentinel, "should have been set");
     result_oop = string_at_impl(this_cp, cp_index, cache_index, CHECK_NULL);
     break;
 
   case JVM_CONSTANT_MethodHandle:
-    {
+    { PerfTraceTimedEvent timer(ClassLoader::perf_resolve_method_handle_time(),
+                                ClassLoader::perf_resolve_method_handle_count(),
+                                THREAD->class_being_initialized() == nullptr);
       int ref_kind                 = this_cp->method_handle_ref_kind_at(cp_index);
       int callee_index             = this_cp->method_handle_klass_index_at(cp_index);
       Symbol*  name =      this_cp->method_handle_name_ref_at(cp_index);
       Symbol*  signature = this_cp->method_handle_signature_ref_at(cp_index);
       constantTag m_tag  = this_cp->tag_at(this_cp->method_handle_index_at(cp_index));
@@ -1118,11 +1434,13 @@
       result_oop = value();
       break;
     }
 
   case JVM_CONSTANT_MethodType:
-    {
+    { PerfTraceTimedEvent timer(ClassLoader::perf_resolve_method_type_time(),
+                                ClassLoader::perf_resolve_method_type_count(),
+                                THREAD->class_being_initialized() == nullptr);
       Symbol*  signature = this_cp->method_type_signature_at(cp_index);
       { ResourceMark rm(THREAD);
         log_debug(class, resolve)("resolve JVM_CONSTANT_MethodType [%d/%d] %s",
                               cp_index, this_cp->method_type_index_at(cp_index),
                               signature->as_C_string());
