8013875: Incorrect vtable index being set during methodHandle creation for static

Wed, 08 May 2013 14:18:03 -0700

author
bharadwaj
date
Wed, 08 May 2013 14:18:03 -0700
changeset 5091
39ead0411f07
parent 5090
0dc028fd5101
child 5094
c272092594bd

8013875: Incorrect vtable index being set during methodHandle creation for static
Summary: Set vtable index as appropriate for static interface methods and for interface methods invoked via invokespecial. To be improved in a later enhancement to CallInfo.
Reviewed-by: jrose, twisti

src/share/vm/prims/methodHandles.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/prims/methodHandles.cpp	Wed May 08 10:14:57 2013 -0400
     1.2 +++ b/src/share/vm/prims/methodHandles.cpp	Wed May 08 14:18:03 2013 -0700
     1.3 @@ -193,19 +193,15 @@
     1.4      flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
     1.5    } else if (mods.is_static()) {
     1.6      flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT);
     1.7 -     // Get vindex from itable if method holder is an interface.
     1.8 -     if (m->method_holder()->is_interface()) {
     1.9 -       vmindex = klassItable::compute_itable_index(m);
    1.10 -     }
    1.11    } else if (receiver_limit != mklass &&
    1.12               !receiver_limit->is_subtype_of(mklass)) {
    1.13      return NULL;  // bad receiver limit
    1.14 -  } else if (receiver_limit->is_interface() &&
    1.15 +  } else if (do_dispatch && receiver_limit->is_interface() &&
    1.16               mklass->is_interface()) {
    1.17      flags |= IS_METHOD | (JVM_REF_invokeInterface << REFERENCE_KIND_SHIFT);
    1.18      receiver_limit = mklass;  // ignore passed-in limit; interfaces are interconvertible
    1.19      vmindex = klassItable::compute_itable_index(m);
    1.20 -  } else if (mklass != receiver_limit && mklass->is_interface()) {
    1.21 +  } else if (do_dispatch && mklass != receiver_limit && mklass->is_interface()) {
    1.22      flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT);
    1.23      // it is a miranda method, so m->vtable_index is not what we want
    1.24      ResourceMark rm;
    1.25 @@ -250,10 +246,25 @@
    1.26    }
    1.27    methodHandle m = info.resolved_method();
    1.28    KlassHandle defc = info.resolved_klass();
    1.29 -  int vmindex = -1;
    1.30 +  int vmindex = Method::invalid_vtable_index;
    1.31    if (defc->is_interface() && m->method_holder()->is_interface()) {
    1.32 -    // LinkResolver does not report itable indexes!  (fix this?)
    1.33 -    vmindex = klassItable::compute_itable_index(m());
    1.34 +    // static interface methods do not reference vtable or itable
    1.35 +    if (m->is_static()) {
    1.36 +      vmindex = Method::nonvirtual_vtable_index;
    1.37 +    }
    1.38 +    // interface methods invoked via invokespecial also
    1.39 +    // do not reference vtable or itable.
    1.40 +    int ref_kind = ((java_lang_invoke_MemberName::flags(mname()) >>
    1.41 +                     REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK);
    1.42 +    if (ref_kind == JVM_REF_invokeSpecial) {
    1.43 +      vmindex = Method::nonvirtual_vtable_index;
    1.44 +    }
    1.45 +    // If neither m is static nor ref_kind is invokespecial,
    1.46 +    // set it to itable index.
    1.47 +    if (vmindex == Method::invalid_vtable_index) {
    1.48 +      // LinkResolver does not report itable indexes!  (fix this?)
    1.49 +      vmindex = klassItable::compute_itable_index(m());
    1.50 +    }
    1.51    } else if (m->can_be_statically_bound()) {
    1.52      // LinkResolver reports vtable index even for final methods!
    1.53      vmindex = Method::nonvirtual_vtable_index;
    1.54 @@ -665,11 +676,9 @@
    1.55    case IS_METHOD:
    1.56      {
    1.57        CallInfo result;
    1.58 -      bool do_dispatch = true;  // default, neutral setting
    1.59        {
    1.60          assert(!HAS_PENDING_EXCEPTION, "");
    1.61          if (ref_kind == JVM_REF_invokeStatic) {
    1.62 -          //do_dispatch = false;  // no need, since statics are never dispatched
    1.63            LinkResolver::resolve_static_call(result,
    1.64                          defc, name, type, KlassHandle(), false, false, THREAD);
    1.65          } else if (ref_kind == JVM_REF_invokeInterface) {
    1.66 @@ -680,7 +689,6 @@
    1.67            LinkResolver::resolve_handle_call(result,
    1.68                          defc, name, type, KlassHandle(), THREAD);
    1.69          } else if (ref_kind == JVM_REF_invokeSpecial) {
    1.70 -          do_dispatch = false;  // force non-virtual linkage
    1.71            LinkResolver::resolve_special_call(result,
    1.72                          defc, name, type, KlassHandle(), false, THREAD);
    1.73          } else if (ref_kind == JVM_REF_invokeVirtual) {

mercurial