< prev index next >
src/hotspot/share/c1/c1_GraphBuilder.cpp
Print this page
*** 1940,2004 ****
if ((code == Bytecodes::_invokevirtual && callee_holder->is_initialized()) ||
(code == Bytecodes::_invokeinterface && callee_holder->is_initialized() && !actual_recv->is_interface())) {
// Use CHA on the receiver to select a more precise method.
cha_monomorphic_target = target->find_monomorphic_target(calling_klass, callee_holder, actual_recv);
} else if (code == Bytecodes::_invokeinterface && callee_holder->is_loaded() && receiver != NULL) {
! // if there is only one implementor of this interface then we
// may be able bind this invoke directly to the implementing
// klass but we need both a dependence on the single interface
// and on the method we bind to. Additionally since all we know
// about the receiver type is the it's supposed to implement the
// interface we have to insert a check that it's the class we
// expect. Interface types are not checked by the verifier so
// they are roughly equivalent to Object.
! ciInstanceKlass* singleton = NULL;
! if (target->holder()->nof_implementors() == 1) {
! singleton = target->holder()->implementor();
! assert(singleton != NULL && singleton != target->holder(),
! "just checking");
!
! assert(holder->is_interface(), "invokeinterface to non interface?");
! ciInstanceKlass* decl_interface = (ciInstanceKlass*)holder;
! // the number of implementors for decl_interface is less or
// equal to the number of implementors for target->holder() so
// if number of implementors of target->holder() == 1 then
// number of implementors for decl_interface is 0 or 1. If
// it's 0 then no class implements decl_interface and there's
// no point in inlining.
! if (!holder->is_loaded() || decl_interface->nof_implementors() != 1 || decl_interface->has_nonstatic_concrete_methods()) {
! singleton = NULL;
! }
! }
! if (singleton) {
! cha_monomorphic_target = target->find_monomorphic_target(calling_klass, target->holder(), singleton);
if (cha_monomorphic_target != NULL) {
// If CHA is able to bind this invoke then update the class
// to match that class, otherwise klass will refer to the
// interface.
klass = cha_monomorphic_target->holder();
! actual_recv = target->holder();
// insert a check it's really the expected class.
CheckCast* c = new CheckCast(klass, receiver, copy_state_for_exception());
c->set_incompatible_class_change_check();
c->set_direct_compare(klass->is_final());
// pass the result of the checkcast so that the compiler has
// more accurate type info in the inlinee
better_receiver = append_split(c);
}
}
}
}
-
- if (cha_monomorphic_target != NULL) {
- if (cha_monomorphic_target->is_abstract()) {
- // Do not optimize for abstract methods
- cha_monomorphic_target = NULL;
- }
}
if (cha_monomorphic_target != NULL) {
if (!(target->is_final_method())) {
// If we inlined because CHA revealed only a single target method,
// then we are dependent on that target method not getting overridden
// by dynamic class loading. Be sure to test the "static" receiver
// dest_method here, as opposed to the actual receiver, which may
--- 1940,1996 ----
if ((code == Bytecodes::_invokevirtual && callee_holder->is_initialized()) ||
(code == Bytecodes::_invokeinterface && callee_holder->is_initialized() && !actual_recv->is_interface())) {
// Use CHA on the receiver to select a more precise method.
cha_monomorphic_target = target->find_monomorphic_target(calling_klass, callee_holder, actual_recv);
} else if (code == Bytecodes::_invokeinterface && callee_holder->is_loaded() && receiver != NULL) {
! assert(callee_holder->is_interface(), "invokeinterface to non interface?");
! // If there is only one implementor of this interface then we
// may be able bind this invoke directly to the implementing
// klass but we need both a dependence on the single interface
// and on the method we bind to. Additionally since all we know
// about the receiver type is the it's supposed to implement the
// interface we have to insert a check that it's the class we
// expect. Interface types are not checked by the verifier so
// they are roughly equivalent to Object.
! // The number of implementors for declared_interface is less or
// equal to the number of implementors for target->holder() so
// if number of implementors of target->holder() == 1 then
// number of implementors for decl_interface is 0 or 1. If
// it's 0 then no class implements decl_interface and there's
// no point in inlining.
! ciInstanceKlass* singleton = NULL;
! ciInstanceKlass* declared_interface = callee_holder;
! if (declared_interface->nof_implementors() == 1 &&
! (!target->is_default_method() || target->is_overpass()) /* CHA doesn't support default methods yet. */) {
! singleton = declared_interface->implementor();
! assert(singleton != NULL && singleton != declared_interface, "");
! cha_monomorphic_target = target->find_monomorphic_target(calling_klass, declared_interface, singleton);
if (cha_monomorphic_target != NULL) {
+ if (cha_monomorphic_target->holder() != compilation()->env()->Object_klass()) {
// If CHA is able to bind this invoke then update the class
// to match that class, otherwise klass will refer to the
// interface.
klass = cha_monomorphic_target->holder();
! actual_recv = declared_interface;
// insert a check it's really the expected class.
CheckCast* c = new CheckCast(klass, receiver, copy_state_for_exception());
c->set_incompatible_class_change_check();
c->set_direct_compare(klass->is_final());
// pass the result of the checkcast so that the compiler has
// more accurate type info in the inlinee
better_receiver = append_split(c);
+ } else {
+ cha_monomorphic_target = NULL; // subtype check against Object is useless
}
}
}
}
}
if (cha_monomorphic_target != NULL) {
+ assert(!cha_monomorphic_target->is_abstract(), "");
if (!(target->is_final_method())) {
// If we inlined because CHA revealed only a single target method,
// then we are dependent on that target method not getting overridden
// by dynamic class loading. Be sure to test the "static" receiver
// dest_method here, as opposed to the actual receiver, which may
< prev index next >