changeset 511:d8eb5f191045

meth-info-8008688.patch: JVM tweaks
author jrose
date Thu, 02 May 2013 19:26:12 -0700
parents c4e42349c4b6
children f3dba3c8e66b
files meth-info-8008688.patch
diffstat 1 files changed, 85 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/meth-info-8008688.patch	Thu May 02 19:26:12 2013 -0700
@@ -0,0 +1,85 @@
+Temporary hacks needed to get MethodHandleInfo unit tests working on all kinds of methods.
+These work around deficiencies in CallInfo and the if/else chains that use CallInfo data.
+
+diff --git a/src/share/vm/oops/klassVtable.cpp b/src/share/vm/oops/klassVtable.cpp
+--- a/src/share/vm/oops/klassVtable.cpp
++++ b/src/share/vm/oops/klassVtable.cpp
+@@ -519,6 +519,9 @@
+ // check if a method is a miranda method, given a class's methods table and it's super
+ // the caller must make sure that the method belongs to an interface implemented by the class
+ bool klassVtable::is_miranda(Method* m, Array<Method*>* class_methods, Klass* super) {
++  if (m->is_static()) {
++    return false;
++  }
+   Symbol* name = m->name();
+   Symbol* signature = m->signature();
+   if (InstanceKlass::find_method(class_methods, name, signature) == NULL) {
+diff --git a/src/share/vm/prims/methodHandles.cpp b/src/share/vm/prims/methodHandles.cpp
+--- a/src/share/vm/prims/methodHandles.cpp
++++ b/src/share/vm/prims/methodHandles.cpp
+@@ -192,19 +192,16 @@
+     flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
+   } else if (mods.is_static()) {
+     flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT);
+-     // Get vindex from itable if method holder is an interface.
+-     if (m->method_holder()->is_interface()) {
+-       vmindex = klassItable::compute_itable_index(m);
+-     }
+   } else if (receiver_limit != mklass &&
+              !receiver_limit->is_subtype_of(mklass)) {
+     return NULL;  // bad receiver limit
+-  } else if (receiver_limit->is_interface() &&
++  } else if (do_dispatch &&
++             receiver_limit->is_interface() &&
+              mklass->is_interface()) {
+     flags |= IS_METHOD | (JVM_REF_invokeInterface << REFERENCE_KIND_SHIFT);
+     receiver_limit = mklass;  // ignore passed-in limit; interfaces are interconvertible
+     vmindex = klassItable::compute_itable_index(m);
+-  } else if (mklass != receiver_limit && mklass->is_interface()) {
++  } else if (do_dispatch && mklass != receiver_limit && mklass->is_interface()) {
+     flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT);
+     // it is a miranda method, so m->vtable_index is not what we want
+     ResourceMark rm;
+@@ -259,6 +256,14 @@
+   } else {
+     vmindex = info.vtable_index();
+   }
++
++  // @@ Hack for default and static interface methods.  Should be gated on info.has_itable_index, etc.
++  if (defc->is_interface() &&
++      (m->is_static() ||
++       ((java_lang_invoke_MemberName::flags(mname()) >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK) == JVM_REF_invokeSpecial)) {
++    vmindex = Method::nonvirtual_vtable_index; //FIXME; should have been in CallInfo
++  }
++
+   oop res = init_method_MemberName(mname, m(), (vmindex >= 0), defc());
+   assert(res == NULL || (java_lang_invoke_MemberName::vmindex(res) == vmindex), "");
+   return Handle(THREAD, res);
+@@ -664,11 +669,9 @@
+   case IS_METHOD:
+     {
+       CallInfo result;
+-      bool do_dispatch = true;  // default, neutral setting
+       {
+         assert(!HAS_PENDING_EXCEPTION, "");
+         if (ref_kind == JVM_REF_invokeStatic) {
+-          //do_dispatch = false;  // no need, since statics are never dispatched
+           LinkResolver::resolve_static_call(result,
+                         defc, name, type, KlassHandle(), false, false, THREAD);
+         } else if (ref_kind == JVM_REF_invokeInterface) {
+@@ -679,7 +682,6 @@
+           LinkResolver::resolve_handle_call(result,
+                         defc, name, type, KlassHandle(), THREAD);
+         } else if (ref_kind == JVM_REF_invokeSpecial) {
+-          do_dispatch = false;  // force non-virtual linkage
+           LinkResolver::resolve_special_call(result,
+                         defc, name, type, KlassHandle(), false, THREAD);
+         } else if (ref_kind == JVM_REF_invokeVirtual) {
+@@ -692,6 +694,7 @@
+           return empty;
+         }
+       }
++      // FIXME: LinkResolver::resolve_{static,special}_call on interface should set CallInfo.is_statically_bound() == true
+       return init_method_MemberName(mname, result, THREAD);
+     }
+   case IS_CONSTRUCTOR: