7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space
authortwisti
Mon, 18 Apr 2011 01:33:28 -0700
changeset 9323 20cc2230dc8a
parent 9141 b9b83b001cac
child 9324 c2e97d1d66d2
7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space Reviewed-by: kvn, jrose
hotspot/src/share/vm/ci/ciMethod.hpp
hotspot/src/share/vm/memory/genOopClosures.hpp
hotspot/src/share/vm/prims/methodHandleWalk.cpp
hotspot/src/share/vm/prims/methodHandles.cpp
hotspot/src/share/vm/prims/methodHandles.hpp
hotspot/src/share/vm/runtime/sharedRuntime.cpp
--- a/hotspot/src/share/vm/ci/ciMethod.hpp	Fri Apr 15 08:29:26 2011 -0700
+++ b/hotspot/src/share/vm/ci/ciMethod.hpp	Mon Apr 18 01:33:28 2011 -0700
@@ -276,9 +276,9 @@
   void print_short_name(outputStream* st = tty);
 
   methodOop get_method_handle_target() {
-    klassOop receiver_limit_oop = NULL;
-    int flags = 0;
-    return MethodHandles::decode_method(get_oop(), receiver_limit_oop, flags);
+    KlassHandle receiver_limit; int flags = 0;
+    methodHandle m = MethodHandles::decode_method(get_oop(), receiver_limit, flags);
+    return m();
   }
 };
 
--- a/hotspot/src/share/vm/memory/genOopClosures.hpp	Fri Apr 15 08:29:26 2011 -0700
+++ b/hotspot/src/share/vm/memory/genOopClosures.hpp	Mon Apr 18 01:33:28 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -175,7 +175,7 @@
  protected:
   template <class T> inline void do_oop_work(T* p) {
     oop obj = oopDesc::load_decode_heap_oop(p);
-    guarantee(obj->is_oop_or_null(), "invalid oop");
+    guarantee(obj->is_oop_or_null(), err_msg("invalid oop: " INTPTR_FORMAT, obj));
   }
  public:
   virtual void do_oop(oop* p);
--- a/hotspot/src/share/vm/prims/methodHandleWalk.cpp	Fri Apr 15 08:29:26 2011 -0700
+++ b/hotspot/src/share/vm/prims/methodHandleWalk.cpp	Mon Apr 18 01:33:28 2011 -0700
@@ -82,10 +82,8 @@
 
 void MethodHandleChain::set_last_method(oop target, TRAPS) {
   _is_last = true;
-  klassOop receiver_limit_oop = NULL;
-  int flags = 0;
-  methodOop m = MethodHandles::decode_method(target, receiver_limit_oop, flags);
-  _last_method = methodHandle(THREAD, m);
+  KlassHandle receiver_limit; int flags = 0;
+  _last_method = MethodHandles::decode_method(target, receiver_limit, flags);
   if ((flags & MethodHandles::_dmf_has_receiver) == 0)
     _last_invoke = Bytecodes::_invokestatic;
   else if ((flags & MethodHandles::_dmf_does_dispatch) == 0)
--- a/hotspot/src/share/vm/prims/methodHandles.cpp	Fri Apr 15 08:29:26 2011 -0700
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp	Mon Apr 18 01:33:28 2011 -0700
@@ -153,9 +153,9 @@
 // and local, like parse a data structure.  For speed, such methods work on plain
 // oops, not handles.  Trapping methods uniformly operate on handles.
 
-methodOop MethodHandles::decode_vmtarget(oop vmtarget, int vmindex, oop mtype,
-                                         klassOop& receiver_limit_result, int& decode_flags_result) {
-  if (vmtarget == NULL)  return NULL;
+methodHandle MethodHandles::decode_vmtarget(oop vmtarget, int vmindex, oop mtype,
+                                            KlassHandle& receiver_limit_result, int& decode_flags_result) {
+  if (vmtarget == NULL)  return methodHandle();
   assert(methodOopDesc::nonvirtual_vtable_index < 0, "encoding");
   if (vmindex < 0) {
     // this DMH performs no dispatch; it is directly bound to a methodOop
@@ -198,20 +198,20 @@
 // MemberName and DirectMethodHandle have the same linkage to the JVM internals.
 // (MemberName is the non-operational name used for queries and setup.)
 
-methodOop MethodHandles::decode_DirectMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) {
+methodHandle MethodHandles::decode_DirectMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result) {
   oop vmtarget = java_lang_invoke_DirectMethodHandle::vmtarget(mh);
   int vmindex  = java_lang_invoke_DirectMethodHandle::vmindex(mh);
   oop mtype    = java_lang_invoke_DirectMethodHandle::type(mh);
   return decode_vmtarget(vmtarget, vmindex, mtype, receiver_limit_result, decode_flags_result);
 }
 
-methodOop MethodHandles::decode_BoundMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) {
+methodHandle MethodHandles::decode_BoundMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result) {
   assert(java_lang_invoke_BoundMethodHandle::is_instance(mh), "");
   assert(mh->klass() != SystemDictionary::AdapterMethodHandle_klass(), "");
   for (oop bmh = mh;;) {
     // Bound MHs can be stacked to bind several arguments.
     oop target = java_lang_invoke_MethodHandle::vmtarget(bmh);
-    if (target == NULL)  return NULL;
+    if (target == NULL)  return methodHandle();
     decode_flags_result |= MethodHandles::_dmf_binds_argument;
     klassOop tk = target->klass();
     if (tk == SystemDictionary::BoundMethodHandle_klass()) {
@@ -236,14 +236,14 @@
   }
 }
 
-methodOop MethodHandles::decode_AdapterMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) {
+methodHandle MethodHandles::decode_AdapterMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result) {
   assert(mh->klass() == SystemDictionary::AdapterMethodHandle_klass(), "");
   for (oop amh = mh;;) {
     // Adapter MHs can be stacked to convert several arguments.
     int conv_op = adapter_conversion_op(java_lang_invoke_AdapterMethodHandle::conversion(amh));
     decode_flags_result |= (_dmf_adapter_lsb << conv_op) & _DMF_ADAPTER_MASK;
     oop target = java_lang_invoke_MethodHandle::vmtarget(amh);
-    if (target == NULL)  return NULL;
+    if (target == NULL)  return methodHandle();
     klassOop tk = target->klass();
     if (tk == SystemDictionary::AdapterMethodHandle_klass()) {
       amh = target;
@@ -255,8 +255,8 @@
   }
 }
 
-methodOop MethodHandles::decode_MethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) {
-  if (mh == NULL)  return NULL;
+methodHandle MethodHandles::decode_MethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result) {
+  if (mh == NULL)  return methodHandle();
   klassOop mhk = mh->klass();
   assert(java_lang_invoke_MethodHandle::is_subclass(mhk), "must be a MethodHandle");
   if (mhk == SystemDictionary::DirectMethodHandle_klass()) {
@@ -270,7 +270,7 @@
     return decode_BoundMethodHandle(mh, receiver_limit_result, decode_flags_result);
   } else {
     assert(false, "cannot parse this MH");
-    return NULL;              // random MH?
+    return methodHandle();  // random MH?
   }
 }
 
@@ -299,9 +299,9 @@
 
 // A trusted party is handing us a cookie to determine a method.
 // Let's boil it down to the method oop they really want.
-methodOop MethodHandles::decode_method(oop x, klassOop& receiver_limit_result, int& decode_flags_result) {
+methodHandle MethodHandles::decode_method(oop x, KlassHandle& receiver_limit_result, int& decode_flags_result) {
   decode_flags_result = 0;
-  receiver_limit_result = NULL;
+  receiver_limit_result = KlassHandle();
   klassOop xk = x->klass();
   if (xk == Universe::methodKlassObj()) {
     return decode_methodOop((methodOop) x, decode_flags_result);
@@ -329,7 +329,7 @@
     assert(!x->is_method(), "already checked");
     assert(!java_lang_invoke_MemberName::is_instance(x), "already checked");
   }
-  return NULL;
+  return methodHandle();
 }
 
 
@@ -389,11 +389,10 @@
     int offset = instanceKlass::cast(k)->offset_from_fields(slot);
     init_MemberName(mname_oop, k, accessFlags_from(mods), offset);
   } else {
-    int decode_flags = 0; klassOop receiver_limit = NULL;
-    methodOop m = MethodHandles::decode_method(target_oop,
-                                               receiver_limit, decode_flags);
+    KlassHandle receiver_limit; int decode_flags = 0;
+    methodHandle m = MethodHandles::decode_method(target_oop, receiver_limit, decode_flags);
     bool do_dispatch = ((decode_flags & MethodHandles::_dmf_does_dispatch) != 0);
-    init_MemberName(mname_oop, m, do_dispatch);
+    init_MemberName(mname_oop, m(), do_dispatch);
   }
 }
 
@@ -423,13 +422,14 @@
 }
 
 
-methodOop MethodHandles::decode_MemberName(oop mname, klassOop& receiver_limit_result, int& decode_flags_result) {
+methodHandle MethodHandles::decode_MemberName(oop mname, KlassHandle& receiver_limit_result, int& decode_flags_result) {
+  methodHandle empty;
   int flags  = java_lang_invoke_MemberName::flags(mname);
-  if ((flags & (IS_METHOD | IS_CONSTRUCTOR)) == 0)  return NULL;  // not invocable
+  if ((flags & (IS_METHOD | IS_CONSTRUCTOR)) == 0)  return empty;  // not invocable
   oop vmtarget = java_lang_invoke_MemberName::vmtarget(mname);
   int vmindex  = java_lang_invoke_MemberName::vmindex(mname);
-  if (vmindex == VM_INDEX_UNINITIALIZED)  return NULL; // not resolved
-  methodOop m = decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit_result, decode_flags_result);
+  if (vmindex == VM_INDEX_UNINITIALIZED)  return empty;  // not resolved
+  methodHandle m = decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit_result, decode_flags_result);
   oop clazz = java_lang_invoke_MemberName::clazz(mname);
   if (clazz != NULL && java_lang_Class::is_instance(clazz)) {
     klassOop klass = java_lang_Class::as_klassOop(clazz);
@@ -439,9 +439,7 @@
 }
 
 // convert the external string or reflective type to an internal signature
-Symbol* MethodHandles::convert_to_signature(oop type_str,
-                                            bool polymorphic,
-                                            TRAPS) {
+Symbol* MethodHandles::convert_to_signature(oop type_str, bool polymorphic, TRAPS) {
   if (java_lang_invoke_MethodType::is_instance(type_str)) {
     return java_lang_invoke_MethodType::as_signature(type_str, polymorphic, CHECK_NULL);
   } else if (java_lang_Class::is_instance(type_str)) {
@@ -474,48 +472,48 @@
 #endif
   if (java_lang_invoke_MemberName::vmindex(mname()) != VM_INDEX_UNINITIALIZED)
     return;  // already resolved
-  oop defc_oop = java_lang_invoke_MemberName::clazz(mname());
-  oop name_str = java_lang_invoke_MemberName::name(mname());
-  oop type_str = java_lang_invoke_MemberName::type(mname());
-  int flags    = java_lang_invoke_MemberName::flags(mname());
+  Handle defc_oop(THREAD, java_lang_invoke_MemberName::clazz(mname()));
+  Handle name_str(THREAD, java_lang_invoke_MemberName::name( mname()));
+  Handle type_str(THREAD, java_lang_invoke_MemberName::type( mname()));
+  int    flags    =       java_lang_invoke_MemberName::flags(mname());
 
-  if (defc_oop == NULL || name_str == NULL || type_str == NULL) {
+  if (defc_oop.is_null() || name_str.is_null() || type_str.is_null()) {
     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to resolve");
   }
-  klassOop defc_klassOop = java_lang_Class::as_klassOop(defc_oop);
-  defc_oop = NULL;  // safety
-  if (defc_klassOop == NULL)  return;  // a primitive; no resolution possible
-  if (!Klass::cast(defc_klassOop)->oop_is_instance()) {
-    if (!Klass::cast(defc_klassOop)->oop_is_array())  return;
-    defc_klassOop = SystemDictionary::Object_klass();
+
+  instanceKlassHandle defc;
+  {
+    klassOop defc_klassOop = java_lang_Class::as_klassOop(defc_oop());
+    if (defc_klassOop == NULL)  return;  // a primitive; no resolution possible
+    if (!Klass::cast(defc_klassOop)->oop_is_instance()) {
+      if (!Klass::cast(defc_klassOop)->oop_is_array())  return;
+      defc_klassOop = SystemDictionary::Object_klass();
+    }
+    defc = instanceKlassHandle(THREAD, defc_klassOop);
   }
-  instanceKlassHandle defc(THREAD, defc_klassOop);
-  defc_klassOop = NULL;  // safety
   if (defc.is_null()) {
     THROW_MSG(vmSymbols::java_lang_InternalError(), "primitive class");
   }
-  defc->link_class(CHECK);
+  defc->link_class(CHECK);  // possible safepoint
 
   // convert the external string name to an internal symbol
-  TempNewSymbol name = java_lang_String::as_symbol_or_null(name_str);
+  TempNewSymbol name = java_lang_String::as_symbol_or_null(name_str());
   if (name == NULL)  return;  // no such name
-  name_str = NULL;  // safety
 
   Handle polymorphic_method_type;
   bool polymorphic_signature = false;
   if ((flags & ALL_KINDS) == IS_METHOD &&
       (defc() == SystemDictionary::MethodHandle_klass() &&
-       methodOopDesc::is_method_handle_invoke_name(name)))
+       methodOopDesc::is_method_handle_invoke_name(name))) {
     polymorphic_signature = true;
+  }
 
   // convert the external string or reflective type to an internal signature
-  TempNewSymbol type = convert_to_signature(type_str, polymorphic_signature, CHECK);
-  if (java_lang_invoke_MethodType::is_instance(type_str) && polymorphic_signature) {
-    polymorphic_method_type = Handle(THREAD, type_str);  //preserve exactly
+  TempNewSymbol type = convert_to_signature(type_str(), polymorphic_signature, CHECK);
+  if (java_lang_invoke_MethodType::is_instance(type_str()) && polymorphic_signature) {
+    polymorphic_method_type = type_str;  // preserve exactly
   }
-
   if (type == NULL)  return;  // no such signature exists in the VM
-  type_str = NULL; // safety
 
   // Time to do the lookup.
   switch (flags & ALL_KINDS) {
@@ -560,8 +558,8 @@
       java_lang_invoke_MemberName::set_vmtarget(mname(), vmtarget);
       java_lang_invoke_MemberName::set_vmindex(mname(),  vmindex);
       java_lang_invoke_MemberName::set_modifiers(mname(), mods);
-      DEBUG_ONLY(int junk; klassOop junk2);
-      assert(decode_MemberName(mname(), junk2, junk) == result.resolved_method()(),
+      DEBUG_ONLY(KlassHandle junk1; int junk2);
+      assert(decode_MemberName(mname(), junk1, junk2) == result.resolved_method(),
              "properly stored for later decoding");
       return;
     }
@@ -589,8 +587,8 @@
       java_lang_invoke_MemberName::set_vmtarget(mname(), vmtarget);
       java_lang_invoke_MemberName::set_vmindex(mname(),  vmindex);
       java_lang_invoke_MemberName::set_modifiers(mname(), mods);
-      DEBUG_ONLY(int junk; klassOop junk2);
-      assert(decode_MemberName(mname(), junk2, junk) == result.resolved_method()(),
+      DEBUG_ONLY(KlassHandle junk1; int junk2);
+      assert(decode_MemberName(mname(), junk1, junk2) == result.resolved_method(),
              "properly stored for later decoding");
       return;
     }
@@ -677,16 +675,14 @@
   case IS_METHOD:
   case IS_CONSTRUCTOR:
     {
-      klassOop receiver_limit = NULL;
-      int      decode_flags   = 0;
-      methodHandle m(THREAD, decode_vmtarget(vmtarget, vmindex, NULL,
-                                             receiver_limit, decode_flags));
+      KlassHandle receiver_limit; int decode_flags = 0;
+      methodHandle m = decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit, decode_flags);
       if (m.is_null())  break;
       if (!have_defc) {
         klassOop defc = m->method_holder();
-        if (receiver_limit != NULL && receiver_limit != defc
-            && Klass::cast(receiver_limit)->is_subtype_of(defc))
-          defc = receiver_limit;
+        if (receiver_limit.not_null() && receiver_limit() != defc
+            && Klass::cast(receiver_limit())->is_subtype_of(defc))
+          defc = receiver_limit();
         java_lang_invoke_MemberName::set_clazz(mname(), Klass::cast(defc)->java_mirror());
       }
       if (!have_name) {
@@ -884,10 +880,9 @@
   // - AMH can have methodOop for static invoke with bound receiver
   // - DMH can have methodOop for static invoke (on variable receiver)
   // - DMH can have klassOop for dispatched (non-static) invoke
-  klassOop receiver_limit = NULL;
-  int decode_flags = 0;
-  methodOop m = decode_MethodHandle(mh(), receiver_limit, decode_flags);
-  if (m == NULL)  return NULL;
+  KlassHandle receiver_limit; int decode_flags = 0;
+  methodHandle m = decode_MethodHandle(mh(), receiver_limit, decode_flags);
+  if (m.is_null())  return NULL;
   switch (format) {
   case ETF_REFLECT_METHOD:
     // same as jni_ToReflectedMethod:
@@ -903,10 +898,10 @@
       if (SystemDictionary::MemberName_klass() == NULL)  break;
       instanceKlassHandle mname_klass(THREAD, SystemDictionary::MemberName_klass());
       mname_klass->initialize(CHECK_NULL);
-      Handle mname = mname_klass->allocate_instance_handle(CHECK_NULL);
+      Handle mname = mname_klass->allocate_instance_handle(CHECK_NULL);  // possible safepoint
       java_lang_invoke_MemberName::set_vmindex(mname(), VM_INDEX_UNINITIALIZED);
       bool do_dispatch = ((decode_flags & MethodHandles::_dmf_does_dispatch) != 0);
-      init_MemberName(mname(), m, do_dispatch);
+      init_MemberName(mname(), m(), do_dispatch);
       expand_MemberName(mname, 0, CHECK_NULL);
       return mname();
     }
@@ -1459,8 +1454,8 @@
   // that links the interpreter calls to the method.  We need the same
   // bits, and will use the same calling sequence code.
 
-  int vmindex = methodOopDesc::garbage_vtable_index;
-  oop vmtarget = NULL;
+  int    vmindex = methodOopDesc::garbage_vtable_index;
+  Handle vmtarget;
 
   instanceKlass::cast(m->method_holder())->link_class(CHECK);
 
@@ -1478,7 +1473,7 @@
   } else if (!do_dispatch || m->can_be_statically_bound()) {
     // We are simulating an invokestatic or invokespecial instruction.
     // Set up the method pointer, just like ConstantPoolCacheEntry::set_method().
-    vmtarget = m();
+    vmtarget = m;
     // this does not help dispatch, but it will make it possible to parse this MH:
     vmindex  = methodOopDesc::nonvirtual_vtable_index;
     assert(vmindex < 0, "(>=0) == do_dispatch");
@@ -1490,7 +1485,7 @@
       // For a DMH, it is done now, when the handle is created.
       Klass* k = Klass::cast(m->method_holder());
       if (k->should_be_initialized()) {
-        k->initialize(CHECK);
+        k->initialize(CHECK);  // possible safepoint
       }
     }
   } else {
@@ -1504,10 +1499,10 @@
 
   if (me == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
 
-  java_lang_invoke_DirectMethodHandle::set_vmtarget(mh(), vmtarget);
-  java_lang_invoke_DirectMethodHandle::set_vmindex(mh(),  vmindex);
-  DEBUG_ONLY(int flags; klassOop rlimit);
-  assert(MethodHandles::decode_method(mh(), rlimit, flags) == m(),
+  java_lang_invoke_DirectMethodHandle::set_vmtarget(mh(), vmtarget());
+  java_lang_invoke_DirectMethodHandle::set_vmindex( mh(), vmindex);
+  DEBUG_ONLY(KlassHandle rlimit; int flags);
+  assert(MethodHandles::decode_method(mh(), rlimit, flags) == m,
          "properly stored for later decoding");
   DEBUG_ONLY(bool actual_do_dispatch = ((flags & _dmf_does_dispatch) != 0));
   assert(!(actual_do_dispatch && !do_dispatch),
@@ -1523,10 +1518,13 @@
                                                            methodHandle m,
                                                            TRAPS) {
   // Verify type.
-  oop receiver = java_lang_invoke_BoundMethodHandle::argument(mh());
+  KlassHandle bound_recv_type;
+  {
+    oop receiver = java_lang_invoke_BoundMethodHandle::argument(mh());
+    if (receiver != NULL)
+      bound_recv_type = KlassHandle(THREAD, receiver->klass());
+  }
   Handle mtype(THREAD, java_lang_invoke_MethodHandle::type(mh()));
-  KlassHandle bound_recv_type;
-  if (receiver != NULL)  bound_recv_type = KlassHandle(THREAD, receiver->klass());
   verify_method_type(m, mtype, true, bound_recv_type, CHECK);
 
   int receiver_pos = m->size_of_parameters() - 1;
@@ -1573,8 +1571,8 @@
 
   java_lang_invoke_BoundMethodHandle::set_vmtarget(mh(), m());
 
-  DEBUG_ONLY(int junk; klassOop junk2);
-  assert(MethodHandles::decode_method(mh(), junk2, junk) == m(), "properly stored for later decoding");
+  DEBUG_ONLY(KlassHandle junk1; int junk2);
+  assert(MethodHandles::decode_method(mh(), junk1, junk2) == m, "properly stored for later decoding");
   assert(decode_MethodHandle_stack_pushes(mh()) == 1, "BMH pushes one stack slot");
 
   // Done!
@@ -1682,8 +1680,11 @@
   }
 
   // Get bound type and required slots.
-  oop ptype_oop = java_lang_invoke_MethodType::ptype(java_lang_invoke_MethodHandle::type(target()), argnum);
-  BasicType ptype = java_lang_Class::as_BasicType(ptype_oop);
+  BasicType ptype;
+  {
+    oop ptype_oop = java_lang_invoke_MethodType::ptype(java_lang_invoke_MethodHandle::type(target()), argnum);
+    ptype = java_lang_Class::as_BasicType(ptype_oop);
+  }
   int slots_pushed = type2size[ptype];
 
   // If (a) the target is a direct non-dispatched method handle,
@@ -1694,13 +1695,12 @@
   if (OptimizeMethodHandles &&
       target->klass() == SystemDictionary::DirectMethodHandle_klass() &&
       (argnum == 0 || java_lang_invoke_DirectMethodHandle::vmindex(target()) < 0)) {
-    int decode_flags = 0; klassOop receiver_limit_oop = NULL;
-    methodHandle m(THREAD, decode_method(target(), receiver_limit_oop, decode_flags));
+    KlassHandle receiver_limit; int decode_flags = 0;
+    methodHandle m = decode_method(target(), receiver_limit, decode_flags);
     if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "DMH failed to decode"); }
     DEBUG_ONLY(int m_vmslots = m->size_of_parameters() - slots_pushed); // pos. of 1st arg.
     assert(java_lang_invoke_BoundMethodHandle::vmslots(mh()) == m_vmslots, "type w/ m sig");
     if (argnum == 0 && (decode_flags & _dmf_has_receiver) != 0) {
-      KlassHandle receiver_limit(THREAD, receiver_limit_oop);
       init_BoundMethodHandle_with_receiver(mh, m,
                                            receiver_limit, decode_flags,
                                            CHECK);
@@ -2019,7 +2019,6 @@
 }
 
 void MethodHandles::init_AdapterMethodHandle(Handle mh, Handle target, int argnum, TRAPS) {
-  oop  argument   = java_lang_invoke_AdapterMethodHandle::argument(mh());
   int  argslot    = java_lang_invoke_AdapterMethodHandle::vmargslot(mh());
   jint conversion = java_lang_invoke_AdapterMethodHandle::conversion(mh());
   jint conv_op    = adapter_conversion_op(conversion);
@@ -2215,18 +2214,14 @@
 
   // which method are we really talking about?
   if (target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
-  oop target_oop = JNIHandles::resolve_non_null(target_jh);
-  if (java_lang_invoke_MemberName::is_instance(target_oop) &&
-      java_lang_invoke_MemberName::vmindex(target_oop) == VM_INDEX_UNINITIALIZED) {
-    Handle mname(THREAD, target_oop);
-    MethodHandles::resolve_MemberName(mname, CHECK);
-    target_oop = mname(); // in case of GC
+  Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
+  if (java_lang_invoke_MemberName::is_instance(target()) &&
+      java_lang_invoke_MemberName::vmindex(target()) == VM_INDEX_UNINITIALIZED) {
+    MethodHandles::resolve_MemberName(target, CHECK);
   }
 
-  int decode_flags = 0; klassOop receiver_limit = NULL;
-  methodHandle m(THREAD,
-                 MethodHandles::decode_method(target_oop,
-                                              receiver_limit, decode_flags));
+  KlassHandle receiver_limit; int decode_flags = 0;
+  methodHandle m = MethodHandles::decode_method(target(), receiver_limit, decode_flags);
   if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "no such method"); }
 
   // The trusted Java code that calls this method should already have performed
@@ -2284,12 +2279,8 @@
     // Target object is a reflective method.  (%%% Do we need this alternate path?)
     Untested("init_BMH of non-MH");
     if (argnum != 0) { THROW(vmSymbols::java_lang_InternalError()); }
-    int decode_flags = 0; klassOop receiver_limit_oop = NULL;
-    methodHandle m(THREAD,
-                   MethodHandles::decode_method(target(),
-                                                receiver_limit_oop,
-                                                decode_flags));
-    KlassHandle receiver_limit(THREAD, receiver_limit_oop);
+    KlassHandle receiver_limit; int decode_flags = 0;
+    methodHandle m = MethodHandles::decode_method(target(), receiver_limit, decode_flags);
     MethodHandles::init_BoundMethodHandle_with_receiver(mh, m,
                                                        receiver_limit,
                                                        decode_flags,
@@ -2424,12 +2415,12 @@
 #ifndef PRODUCT
   if (which >= 0 && which < con_value_count) {
     int con = con_values[which];
-    objArrayOop box = (objArrayOop) JNIHandles::resolve(box_jh);
-    if (box != NULL && box->klass() == Universe::objectArrayKlassObj() && box->length() > 0) {
+    objArrayHandle box(THREAD, (objArrayOop) JNIHandles::resolve(box_jh));
+    if (box.not_null() && box->klass() == Universe::objectArrayKlassObj() && box->length() > 0) {
       const char* str = &con_names[0];
       for (int i = 0; i < which; i++)
         str += strlen(str) + 1;   // skip name and null
-      oop name = java_lang_String::create_oop_from_str(str, CHECK_0);
+      oop name = java_lang_String::create_oop_from_str(str, CHECK_0);  // possible safepoint
       box->obj_at_put(0, name);
     }
     return con;
@@ -2486,10 +2477,10 @@
                                jclass clazz_jh, jstring name_jh, jstring sig_jh,
                                int mflags, jclass caller_jh, jint skip, jobjectArray results_jh)) {
   if (clazz_jh == NULL || results_jh == NULL)  return -1;
-  klassOop k_oop = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz_jh));
+  KlassHandle k(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz_jh)));
 
-  objArrayOop results = (objArrayOop) JNIHandles::resolve(results_jh);
-  if (results == NULL || !results->is_objArray())       return -1;
+  objArrayHandle results(THREAD, (objArrayOop) JNIHandles::resolve(results_jh));
+  if (results.is_null() || !results->is_objArray())  return -1;
 
   TempNewSymbol name = NULL;
   TempNewSymbol sig = NULL;
@@ -2502,20 +2493,20 @@
     if (sig == NULL)  return 0; // a match is not possible
   }
 
-  klassOop caller = NULL;
+  KlassHandle caller;
   if (caller_jh != NULL) {
     oop caller_oop = JNIHandles::resolve_non_null(caller_jh);
     if (!java_lang_Class::is_instance(caller_oop))  return -1;
-    caller = java_lang_Class::as_klassOop(caller_oop);
+    caller = KlassHandle(THREAD, java_lang_Class::as_klassOop(caller_oop));
   }
 
-  if (name != NULL && sig != NULL && results != NULL) {
+  if (name != NULL && sig != NULL && results.not_null()) {
     // try a direct resolve
     // %%% TO DO
   }
 
-  int res = MethodHandles::find_MemberNames(k_oop, name, sig, mflags,
-                                            caller, skip, results);
+  int res = MethodHandles::find_MemberNames(k(), name, sig, mflags,
+                                            caller(), skip, results());
   // TO DO: expand at least some of the MemberNames, to avoid massive callbacks
   return res;
 }
--- a/hotspot/src/share/vm/prims/methodHandles.hpp	Fri Apr 15 08:29:26 2011 -0700
+++ b/hotspot/src/share/vm/prims/methodHandles.hpp	Mon Apr 18 01:33:28 2011 -0700
@@ -265,13 +265,13 @@
   static inline address from_interpreted_entry(EntryKind ek);
 
   // helpers for decode_method.
-  static methodOop decode_methodOop(methodOop m, int& decode_flags_result);
-  static methodOop decode_vmtarget(oop vmtarget, int vmindex, oop mtype, klassOop& receiver_limit_result, int& decode_flags_result);
-  static methodOop decode_MemberName(oop mname, klassOop& receiver_limit_result, int& decode_flags_result);
-  static methodOop decode_MethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result);
-  static methodOop decode_DirectMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result);
-  static methodOop decode_BoundMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result);
-  static methodOop decode_AdapterMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result);
+  static methodOop    decode_methodOop(methodOop m, int& decode_flags_result);
+  static methodHandle decode_vmtarget(oop vmtarget, int vmindex, oop mtype, KlassHandle& receiver_limit_result, int& decode_flags_result);
+  static methodHandle decode_MemberName(oop mname, KlassHandle& receiver_limit_result, int& decode_flags_result);
+  static methodHandle decode_MethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result);
+  static methodHandle decode_DirectMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result);
+  static methodHandle decode_BoundMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result);
+  static methodHandle decode_AdapterMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result);
 
   // Find out how many stack slots an mh pushes or pops.
   // The result is *not* reported as a multiple of stack_move_unit();
@@ -317,7 +317,7 @@
     _dmf_adapter_lsb    = 0x20,
     _DMF_ADAPTER_MASK   = (_dmf_adapter_lsb << CONV_OP_LIMIT) - _dmf_adapter_lsb
   };
-  static methodOop decode_method(oop x, klassOop& receiver_limit_result, int& decode_flags_result);
+  static methodHandle decode_method(oop x, KlassHandle& receiver_limit_result, int& decode_flags_result);
   enum {
     // format of query to getConstant:
     GC_JVM_PUSH_LIMIT = 0,
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Fri Apr 15 08:29:26 2011 -0700
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Mon Apr 18 01:33:28 2011 -0700
@@ -1721,14 +1721,14 @@
         targetArity = ArgumentCount(target->signature()).size();
       }
     }
-    klassOop kignore; int dmf_flags = 0;
-    methodOop actual_method = MethodHandles::decode_method(actual, kignore, dmf_flags);
+    KlassHandle kignore; int dmf_flags = 0;
+    methodHandle actual_method = MethodHandles::decode_method(actual, kignore, dmf_flags);
     if ((dmf_flags & ~(MethodHandles::_dmf_has_receiver |
                        MethodHandles::_dmf_does_dispatch |
                        MethodHandles::_dmf_from_interface)) != 0)
-      actual_method = NULL;  // MH does extra binds, drops, etc.
+      actual_method = methodHandle();  // MH does extra binds, drops, etc.
     bool has_receiver = ((dmf_flags & MethodHandles::_dmf_has_receiver) != 0);
-    if (actual_method != NULL) {
+    if (actual_method.not_null()) {
       mhName = actual_method->signature()->as_C_string();
       mhArity = ArgumentCount(actual_method->signature()).size();
       if (!actual_method->is_static())  mhArity += 1;