< prev index next >

src/share/vm/ci/ciMethod.cpp

Print this page




 783 //
 784 // Given a known receiver klass, find the target for the call.
 785 // Return NULL if the call has no target or the target is abstract.
 786 ciMethod* ciMethod::resolve_invoke(ciKlass* caller, ciKlass* exact_receiver, bool check_access) {
 787    check_is_loaded();
 788    VM_ENTRY_MARK;
 789 
 790    Klass* caller_klass = caller->get_Klass();
 791    Klass* recv         = exact_receiver->get_Klass();
 792    Klass* resolved     = holder()->get_Klass();
 793    Symbol* h_name      = name()->get_symbol();
 794    Symbol* h_signature = signature()->get_symbol();
 795 
 796    LinkInfo link_info(resolved, h_name, h_signature, caller_klass,
 797                       check_access ? LinkInfo::needs_access_check : LinkInfo::skip_access_check);
 798    methodHandle m;
 799    // Only do exact lookup if receiver klass has been linked.  Otherwise,
 800    // the vtable has not been setup, and the LinkResolver will fail.
 801    if (recv->is_array_klass()
 802         ||
 803        InstanceKlass::cast(recv)->is_linked() && !exact_receiver->is_interface()) {
 804      if (holder()->is_interface()) {
 805        m = LinkResolver::resolve_interface_call_or_null(recv, link_info);
 806      } else {
 807        m = LinkResolver::resolve_virtual_call_or_null(recv, link_info);
 808      }
 809    }
 810 
 811    if (m.is_null()) {
 812      // Return NULL only if there was a problem with lookup (uninitialized class, etc.)
 813      return NULL;
 814    }
 815 
 816    ciMethod* result = this;
 817    if (m() != get_Method()) {
 818      result = CURRENT_THREAD_ENV->get_method(m());
 819    }
 820 
 821    // Don't return abstract methods because they aren't
 822    // optimizable or interesting.
 823    if (result->is_abstract()) {


1476         return false;  // receiver should be an oop
1477       }
1478       sbase = 1; // skip receiver
1479       break;
1480     }
1481     case vmIntrinsics::_linkToStatic: {
1482       if (!target->is_static()) {
1483         return false;
1484       }
1485       break;
1486     }
1487     case vmIntrinsics::_invokeBasic: {
1488       if (target->is_static()) {
1489         if (target_sig->type_at(0)->is_primitive_type()) {
1490           return false; // receiver should be an oop
1491         }
1492         rbase = 1; // skip receiver
1493       }
1494       break;
1495     }


1496   }
1497   assert(target_sig->count() - rbase == linker_sig->count() - sbase - has_appendix, "argument count mismatch");
1498   int arg_count = target_sig->count() - rbase;
1499   for (int i = 0; i < arg_count; i++) {
1500     if (!basic_types_match(linker_sig->type_at(sbase + i), target_sig->type_at(rbase + i))) {
1501       return false;
1502     }
1503   }
1504   // Only check the return type if the symbolic info has non-void return type.
1505   // I.e. the return value of the resolved method can be dropped.
1506   if (!linker->return_type()->is_void() &&
1507       !basic_types_match(linker->return_type(), target->return_type())) {
1508     return false;
1509   }
1510   return true; // no mismatch found
1511 }
1512 
1513 // ------------------------------------------------------------------
1514 
1515 #if INCLUDE_TRACE


 783 //
 784 // Given a known receiver klass, find the target for the call.
 785 // Return NULL if the call has no target or the target is abstract.
 786 ciMethod* ciMethod::resolve_invoke(ciKlass* caller, ciKlass* exact_receiver, bool check_access) {
 787    check_is_loaded();
 788    VM_ENTRY_MARK;
 789 
 790    Klass* caller_klass = caller->get_Klass();
 791    Klass* recv         = exact_receiver->get_Klass();
 792    Klass* resolved     = holder()->get_Klass();
 793    Symbol* h_name      = name()->get_symbol();
 794    Symbol* h_signature = signature()->get_symbol();
 795 
 796    LinkInfo link_info(resolved, h_name, h_signature, caller_klass,
 797                       check_access ? LinkInfo::needs_access_check : LinkInfo::skip_access_check);
 798    methodHandle m;
 799    // Only do exact lookup if receiver klass has been linked.  Otherwise,
 800    // the vtable has not been setup, and the LinkResolver will fail.
 801    if (recv->is_array_klass()
 802         ||
 803        (InstanceKlass::cast(recv)->is_linked() && !exact_receiver->is_interface())) {
 804      if (holder()->is_interface()) {
 805        m = LinkResolver::resolve_interface_call_or_null(recv, link_info);
 806      } else {
 807        m = LinkResolver::resolve_virtual_call_or_null(recv, link_info);
 808      }
 809    }
 810 
 811    if (m.is_null()) {
 812      // Return NULL only if there was a problem with lookup (uninitialized class, etc.)
 813      return NULL;
 814    }
 815 
 816    ciMethod* result = this;
 817    if (m() != get_Method()) {
 818      result = CURRENT_THREAD_ENV->get_method(m());
 819    }
 820 
 821    // Don't return abstract methods because they aren't
 822    // optimizable or interesting.
 823    if (result->is_abstract()) {


1476         return false;  // receiver should be an oop
1477       }
1478       sbase = 1; // skip receiver
1479       break;
1480     }
1481     case vmIntrinsics::_linkToStatic: {
1482       if (!target->is_static()) {
1483         return false;
1484       }
1485       break;
1486     }
1487     case vmIntrinsics::_invokeBasic: {
1488       if (target->is_static()) {
1489         if (target_sig->type_at(0)->is_primitive_type()) {
1490           return false; // receiver should be an oop
1491         }
1492         rbase = 1; // skip receiver
1493       }
1494       break;
1495     }
1496     default:
1497       break;
1498   }
1499   assert(target_sig->count() - rbase == linker_sig->count() - sbase - has_appendix, "argument count mismatch");
1500   int arg_count = target_sig->count() - rbase;
1501   for (int i = 0; i < arg_count; i++) {
1502     if (!basic_types_match(linker_sig->type_at(sbase + i), target_sig->type_at(rbase + i))) {
1503       return false;
1504     }
1505   }
1506   // Only check the return type if the symbolic info has non-void return type.
1507   // I.e. the return value of the resolved method can be dropped.
1508   if (!linker->return_type()->is_void() &&
1509       !basic_types_match(linker->return_type(), target->return_type())) {
1510     return false;
1511   }
1512   return true; // no mismatch found
1513 }
1514 
1515 // ------------------------------------------------------------------
1516 
1517 #if INCLUDE_TRACE
< prev index next >