src/share/vm/opto/callGenerator.cpp

changeset 4414
5698813d45eb
parent 4409
d092d1b31229
child 4538
8bd61471a109
     1.1 --- a/src/share/vm/opto/callGenerator.cpp	Tue Jan 08 11:30:51 2013 -0800
     1.2 +++ b/src/share/vm/opto/callGenerator.cpp	Wed Jan 09 15:37:23 2013 -0800
     1.3 @@ -717,6 +717,7 @@
     1.4        (input_not_const || !C->inlining_incrementally() || C->over_inlining_cutoff())) {
     1.5      return CallGenerator::for_mh_late_inline(caller, callee, input_not_const);
     1.6    } else {
     1.7 +    // Out-of-line call.
     1.8      return CallGenerator::for_direct_call(callee);
     1.9    }
    1.10  }
    1.11 @@ -739,7 +740,7 @@
    1.12          guarantee(!target->is_method_handle_intrinsic(), "should not happen");  // XXX remove
    1.13          const int vtable_index = Method::invalid_vtable_index;
    1.14          CallGenerator* cg = C->call_generator(target, vtable_index, false, jvms, true, PROB_ALWAYS, true, true);
    1.15 -        assert (!cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here");
    1.16 +        assert(!cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here");
    1.17          if (cg != NULL && cg->is_inline())
    1.18            return cg;
    1.19        }
    1.20 @@ -787,10 +788,25 @@
    1.21              }
    1.22            }
    1.23          }
    1.24 -        const int vtable_index = Method::invalid_vtable_index;
    1.25 -        const bool call_is_virtual = target->is_abstract();  // FIXME workaround
    1.26 -        CallGenerator* cg = C->call_generator(target, vtable_index, call_is_virtual, jvms, true, PROB_ALWAYS, true, true);
    1.27 -        assert (!cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here");
    1.28 +
    1.29 +        // Try to get the most accurate receiver type
    1.30 +        const bool is_virtual              = (iid == vmIntrinsics::_linkToVirtual);
    1.31 +        const bool is_virtual_or_interface = (is_virtual || iid == vmIntrinsics::_linkToInterface);
    1.32 +        int  vtable_index       = Method::invalid_vtable_index;
    1.33 +        bool call_does_dispatch = false;
    1.34 +
    1.35 +        if (is_virtual_or_interface) {
    1.36 +          ciInstanceKlass* klass = target->holder();
    1.37 +          Node*             receiver_node = kit.argument(0);
    1.38 +          const TypeOopPtr* receiver_type = gvn.type(receiver_node)->isa_oopptr();
    1.39 +          // call_does_dispatch and vtable_index are out-parameters.  They might be changed.
    1.40 +          target = C->optimize_virtual_call(caller, jvms->bci(), klass, target, receiver_type,
    1.41 +                                            is_virtual,
    1.42 +                                            call_does_dispatch, vtable_index);  // out-parameters
    1.43 +        }
    1.44 +
    1.45 +        CallGenerator* cg = C->call_generator(target, vtable_index, call_does_dispatch, jvms, true, PROB_ALWAYS, true, true);
    1.46 +        assert(!cg->is_late_inline() || cg->is_mh_late_inline(), "no late inline here");
    1.47          if (cg != NULL && cg->is_inline())
    1.48            return cg;
    1.49        }

mercurial