611 return JNIHandles::make_local(THREAD, field_holder); 612 C2V_END 613 614 C2V_VMENTRY(jint, getVtableIndexForInterfaceMethod, (JNIEnv *, jobject, jobject jvmci_type, jobject jvmci_method)) 615 ResourceMark rm; 616 Klass* klass = CompilerToVM::asKlass(jvmci_type); 617 Method* method = CompilerToVM::asMethod(jvmci_method); 618 if (klass->is_interface()) { 619 THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Interface %s should be handled in Java code", klass->external_name())); 620 } 621 if (!method->method_holder()->is_interface()) { 622 THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Method %s is not held by an interface, this case should be handled in Java code", method->name_and_sig_as_C_string())); 623 } 624 if (!InstanceKlass::cast(klass)->is_linked()) { 625 THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Class %s must be linked", klass->external_name())); 626 } 627 return LinkResolver::vtable_index_of_interface_method(klass, method); 628 C2V_END 629 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); 632 Klass* caller_klass = CompilerToVM::asKlass(caller_jvmci_type); 633 Method* method = CompilerToVM::asMethod(jvmci_method); 634 635 if (recv_klass->is_array_klass() || (InstanceKlass::cast(recv_klass)->is_linked())) { 636 Klass* holder_klass = method->method_holder(); 637 Symbol* method_name = method->name(); 638 Symbol* method_signature = method->signature(); 639 640 if (holder_klass->is_interface()) { 641 // do link-time resolution to check all access rules. 642 LinkInfo link_info(holder_klass, method_name, method_signature, caller_klass, true); 643 methodHandle resolved_method = LinkResolver::linktime_resolve_interface_method_or_null(link_info); 644 if (resolved_method.is_null() || resolved_method->is_private()) { 645 return NULL; 646 } 647 assert(recv_klass->is_subtype_of(holder_klass), ""); 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 { 653 // do link-time resolution to check all access rules. 654 LinkInfo link_info(holder_klass, method_name, method_signature, caller_klass, true); 655 methodHandle resolved_method = LinkResolver::linktime_resolve_virtual_method_or_null(link_info); 656 if (resolved_method.is_null()) { 657 return NULL; 658 } 659 // do actual lookup (see LinkResolver::runtime_resolve_virtual_method) 660 int vtable_index = Method::invalid_vtable_index; 661 Method* selected_method; 662 663 if (resolved_method->method_holder()->is_interface()) { // miranda method 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 691 692 C2V_VMENTRY(jboolean, hasFinalizableSubclass,(JNIEnv *, jobject, jobject jvmci_type)) 693 Klass* klass = CompilerToVM::asKlass(jvmci_type); 694 assert(klass != NULL, "method must not be called for primitive types"); 695 return Dependencies::find_finalizable_subclass(klass) != NULL; 696 C2V_END 697 698 C2V_VMENTRY(jobject, getClassInitializer, (JNIEnv *, jobject, jobject jvmci_type)) 699 InstanceKlass* klass = (InstanceKlass*) CompilerToVM::asKlass(jvmci_type); 700 oop result = CompilerToVM::get_jvmci_method(klass->class_initializer(), CHECK_NULL); 701 return JNIHandles::make_local(THREAD, result); 702 C2V_END 703 704 C2V_VMENTRY(jlong, getMaxCallTargetOffset, (JNIEnv*, jobject, jlong addr)) 705 address target_addr = (address) addr; 706 if (target_addr != 0x0) { 707 int64_t off_low = (int64_t)target_addr - ((int64_t)CodeCache::low_bound() + sizeof(int)); 708 int64_t off_high = (int64_t)target_addr - ((int64_t)CodeCache::high_bound() + sizeof(int)); 709 return MAX2(ABS(off_low), ABS(off_high)); | 611 return JNIHandles::make_local(THREAD, field_holder); 612 C2V_END 613 614 C2V_VMENTRY(jint, getVtableIndexForInterfaceMethod, (JNIEnv *, jobject, jobject jvmci_type, jobject jvmci_method)) 615 ResourceMark rm; 616 Klass* klass = CompilerToVM::asKlass(jvmci_type); 617 Method* method = CompilerToVM::asMethod(jvmci_method); 618 if (klass->is_interface()) { 619 THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Interface %s should be handled in Java code", klass->external_name())); 620 } 621 if (!method->method_holder()->is_interface()) { 622 THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Method %s is not held by an interface, this case should be handled in Java code", method->name_and_sig_as_C_string())); 623 } 624 if (!InstanceKlass::cast(klass)->is_linked()) { 625 THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Class %s must be linked", klass->external_name())); 626 } 627 return LinkResolver::vtable_index_of_interface_method(klass, method); 628 C2V_END 629 630 C2V_VMENTRY(jobject, resolveMethod, (JNIEnv *, jobject, jobject receiver_jvmci_type, jobject jvmci_method, jobject caller_jvmci_type)) 631 KlassHandle recv_klass = CompilerToVM::asKlass(receiver_jvmci_type); 632 KlassHandle caller_klass = CompilerToVM::asKlass(caller_jvmci_type); 633 methodHandle method = CompilerToVM::asMethod(jvmci_method); 634 635 KlassHandle h_resolved (THREAD, method->method_holder()); 636 Symbol* h_name = method->name(); 637 Symbol* h_signature = method->signature(); 638 639 bool check_access = true; 640 LinkInfo link_info(h_resolved, h_name, h_signature, caller_klass, check_access); 641 methodHandle m; 642 // Only do exact lookup if receiver klass has been linked. Otherwise, 643 // the vtable has not been setup, and the LinkResolver will fail. 644 if (recv_klass->is_array_klass() || 645 InstanceKlass::cast(recv_klass())->is_linked() && !recv_klass->is_interface()) { 646 if (h_resolved->is_interface()) { 647 m = LinkResolver::resolve_interface_call_or_null(recv_klass, link_info); 648 } else { 649 m = LinkResolver::resolve_virtual_call_or_null(recv_klass, link_info); 650 } 651 } 652 653 if (m.is_null()) { 654 // Return NULL only if there was a problem with lookup (uninitialized class, etc.) 655 return NULL; 656 } 657 658 oop result = CompilerToVM::get_jvmci_method(m, CHECK_NULL); 659 return JNIHandles::make_local(THREAD, result); 660 C2V_END 661 662 C2V_VMENTRY(jboolean, hasFinalizableSubclass,(JNIEnv *, jobject, jobject jvmci_type)) 663 Klass* klass = CompilerToVM::asKlass(jvmci_type); 664 assert(klass != NULL, "method must not be called for primitive types"); 665 return Dependencies::find_finalizable_subclass(klass) != NULL; 666 C2V_END 667 668 C2V_VMENTRY(jobject, getClassInitializer, (JNIEnv *, jobject, jobject jvmci_type)) 669 InstanceKlass* klass = (InstanceKlass*) CompilerToVM::asKlass(jvmci_type); 670 oop result = CompilerToVM::get_jvmci_method(klass->class_initializer(), CHECK_NULL); 671 return JNIHandles::make_local(THREAD, result); 672 C2V_END 673 674 C2V_VMENTRY(jlong, getMaxCallTargetOffset, (JNIEnv*, jobject, jlong addr)) 675 address target_addr = (address) addr; 676 if (target_addr != 0x0) { 677 int64_t off_low = (int64_t)target_addr - ((int64_t)CodeCache::low_bound() + sizeof(int)); 678 int64_t off_high = (int64_t)target_addr - ((int64_t)CodeCache::high_bound() + sizeof(int)); 679 return MAX2(ABS(off_low), ABS(off_high)); |