assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier"); assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
// check if private interface method KlassHandleresolved_klass= link_info.resolved_klass(); KlassHandlecurrent_klass= link_info.current_klass();
// This is impossible, if resolve_klass is an interface, we've thrown icce in resolve_method ...
// 1. For invokevirtual, cannot call an interface method ...
// 2. check constant pool tag for called method - must be JVM_CONSTANT_Methodref ...
// 3. lookup method in resolved klass and its super klasses methodHandleresolved_method= lookup_method_in_klasses(link_info, true, false, CHECK_NULL);
// 4. lookup method in all the interfaces implemented by the resolved klass if (resolved_method.is_null() && !resolved_klass->is_array_klass()) { // not found in the class hierarchy resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL);
if (resolved_method.is_null()) { // JSR 292: see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc resolved_method = lookup_polymorphic_method(link_info, (Handle*)NULL, (Handle*)NULL, THREAD); if (HAS_PENDING_EXCEPTION) { nested_exception = Handle(THREAD, PENDING_EXCEPTION); CLEAR_PENDING_EXCEPTION; } } }
// 5. method lookup failed ...
// 6. access checks, access checking may be turned off when calling from within the VM. ...
// Ignore overpasses so statics can be found during resolution Method* result = klass->uncached_lookup_method(name, signature, Klass::skip_overpass);
if (klass->is_array_klass()) { // Only consider klass and super klass for arrays return methodHandle(THREAD, result); }
InstanceKlass* ik = InstanceKlass::cast(klass());
...
// Before considering default methods, check for an overpass in the // current class if a method has not been found. if (result == NULL) { result = ik->find_method(name, signature); }
if (result == NULL) { Array<Method*>* default_methods = ik->default_methods(); if (default_methods != NULL) { result = InstanceKlass::find_method(default_methods, name, signature); } }
// Do linear search to find matching signature. First, quick check // for common case, ignoring overpasses if requested. if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) { return hit; }
// search downwards through overloaded methods int i; for (i = hit - 1; i >= 0; --i) { const Method* constm= methods->at(i); assert(m->is_method(), "must be method"); if (m->name() != name) { break; } if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) { return i; } } // search upwards for (i = hit + 1; i < methods->length(); ++i) { const Method* constm= methods->at(i); assert(m->is_method(), "must be method"); if (m->name() != name) { break; } if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) { return i; } } // not found #ifdef ASSERT const intindex= (skipping_overpass || skipping_static || skipping_private) ? -1 : linear_search(methods, name, signature); assert(-1 == index, "binary search should have found entry %d", index); #endif } return -1; }
// do lookup based on receiver klass using the vtable index if (resolved_method->method_holder()->is_interface()) { // default or miranda method vtable_index = vtable_index_of_interface_method(resolved_klass, resolved_method); assert(vtable_index >= 0 , "we should have valid vtable index at this point");
selected_method = methodHandle(THREAD, recv_klass->method_at_vtable(vtable_index)); } else { // at this point we are sure that resolved_method is virtual and not // a default or miranda method; therefore, it must have a valid vtable index. assert(!resolved_method->has_itable_index(), ""); vtable_index = resolved_method->vtable_index(); // We could get a negative vtable_index for final methods, // because as an optimization they are they are never put in the vtable, // unless they override an existing method. // If we do get a negative, it means the resolved method is the the selected // method, and it can never be changed by an override. if (vtable_index == Method::nonvirtual_vtable_index) { assert(resolved_method->can_be_statically_bound(), "cannot override this method"); selected_method = resolved_method; } else { selected_method = methodHandle(THREAD, recv_klass->method_at_vtable(vtable_index)); } }
...
// setup result result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK); }