626 } |
626 } |
627 return LinkResolver::vtable_index_of_interface_method(klass, method); |
627 return LinkResolver::vtable_index_of_interface_method(klass, method); |
628 C2V_END |
628 C2V_END |
629 |
629 |
630 C2V_VMENTRY(jobject, resolveMethod, (JNIEnv *, jobject, jobject receiver_jvmci_type, jobject jvmci_method, jobject caller_jvmci_type)) |
630 C2V_VMENTRY(jobject, resolveMethod, (JNIEnv *, jobject, jobject receiver_jvmci_type, jobject jvmci_method, jobject caller_jvmci_type)) |
631 Klass* recv_klass = CompilerToVM::asKlass(receiver_jvmci_type); |
631 KlassHandle recv_klass = CompilerToVM::asKlass(receiver_jvmci_type); |
632 Klass* caller_klass = CompilerToVM::asKlass(caller_jvmci_type); |
632 KlassHandle caller_klass = CompilerToVM::asKlass(caller_jvmci_type); |
633 Method* method = CompilerToVM::asMethod(jvmci_method); |
633 methodHandle method = CompilerToVM::asMethod(jvmci_method); |
634 |
634 |
635 if (recv_klass->is_array_klass() || (InstanceKlass::cast(recv_klass)->is_linked())) { |
635 KlassHandle h_resolved (THREAD, method->method_holder()); |
636 Klass* holder_klass = method->method_holder(); |
636 Symbol* h_name = method->name(); |
637 Symbol* method_name = method->name(); |
637 Symbol* h_signature = method->signature(); |
638 Symbol* method_signature = method->signature(); |
638 |
639 |
639 bool check_access = true; |
640 if (holder_klass->is_interface()) { |
640 LinkInfo link_info(h_resolved, h_name, h_signature, caller_klass, check_access); |
641 // do link-time resolution to check all access rules. |
641 methodHandle m; |
642 LinkInfo link_info(holder_klass, method_name, method_signature, caller_klass, true); |
642 // Only do exact lookup if receiver klass has been linked. Otherwise, |
643 methodHandle resolved_method = LinkResolver::linktime_resolve_interface_method_or_null(link_info); |
643 // the vtable has not been setup, and the LinkResolver will fail. |
644 if (resolved_method.is_null() || resolved_method->is_private()) { |
644 if (recv_klass->is_array_klass() || |
645 return NULL; |
645 InstanceKlass::cast(recv_klass())->is_linked() && !recv_klass->is_interface()) { |
646 } |
646 if (h_resolved->is_interface()) { |
647 assert(recv_klass->is_subtype_of(holder_klass), ""); |
647 m = LinkResolver::resolve_interface_call_or_null(recv_klass, link_info); |
648 // do actual lookup |
|
649 methodHandle sel_method = LinkResolver::lookup_instance_method_in_klasses(recv_klass, resolved_method->name(), resolved_method->signature(), CHECK_AND_CLEAR_0); |
|
650 oop result = CompilerToVM::get_jvmci_method(sel_method, CHECK_NULL); |
|
651 return JNIHandles::make_local(THREAD, result); |
|
652 } else { |
648 } else { |
653 // do link-time resolution to check all access rules. |
649 m = LinkResolver::resolve_virtual_call_or_null(recv_klass, link_info); |
654 LinkInfo link_info(holder_klass, method_name, method_signature, caller_klass, true); |
650 } |
655 methodHandle resolved_method = LinkResolver::linktime_resolve_virtual_method_or_null(link_info); |
651 } |
656 if (resolved_method.is_null()) { |
652 |
657 return NULL; |
653 if (m.is_null()) { |
658 } |
654 // Return NULL only if there was a problem with lookup (uninitialized class, etc.) |
659 // do actual lookup (see LinkResolver::runtime_resolve_virtual_method) |
655 return NULL; |
660 int vtable_index = Method::invalid_vtable_index; |
656 } |
661 Method* selected_method; |
657 |
662 |
658 oop result = CompilerToVM::get_jvmci_method(m, CHECK_NULL); |
663 if (resolved_method->method_holder()->is_interface()) { // miranda method |
659 return JNIHandles::make_local(THREAD, result); |
664 vtable_index = LinkResolver::vtable_index_of_interface_method(holder_klass, resolved_method); |
|
665 assert(vtable_index >= 0 , "we should have valid vtable index at this point"); |
|
666 |
|
667 selected_method = recv_klass->method_at_vtable(vtable_index); |
|
668 } else { |
|
669 // at this point we are sure that resolved_method is virtual and not |
|
670 // a miranda method; therefore, it must have a valid vtable index. |
|
671 assert(!resolved_method->has_itable_index(), ""); |
|
672 vtable_index = resolved_method->vtable_index(); |
|
673 // We could get a negative vtable_index for final methods, |
|
674 // because as an optimization they are they are never put in the vtable, |
|
675 // unless they override an existing method. |
|
676 // If we do get a negative, it means the resolved method is the the selected |
|
677 // method, and it can never be changed by an override. |
|
678 if (vtable_index == Method::nonvirtual_vtable_index) { |
|
679 assert(resolved_method->can_be_statically_bound(), "cannot override this method"); |
|
680 selected_method = resolved_method(); |
|
681 } else { |
|
682 selected_method = recv_klass->method_at_vtable(vtable_index); |
|
683 } |
|
684 } |
|
685 oop result = CompilerToVM::get_jvmci_method(selected_method, CHECK_NULL); |
|
686 return JNIHandles::make_local(THREAD, result); |
|
687 } |
|
688 } |
|
689 return NULL; |
|
690 C2V_END |
660 C2V_END |
691 |
661 |
692 C2V_VMENTRY(jboolean, hasFinalizableSubclass,(JNIEnv *, jobject, jobject jvmci_type)) |
662 C2V_VMENTRY(jboolean, hasFinalizableSubclass,(JNIEnv *, jobject, jobject jvmci_type)) |
693 Klass* klass = CompilerToVM::asKlass(jvmci_type); |
663 Klass* klass = CompilerToVM::asKlass(jvmci_type); |
694 assert(klass != NULL, "method must not be called for primitive types"); |
664 assert(klass != NULL, "method must not be called for primitive types"); |