138 if (resolved_klass == NULL) { // 2nd argument defaults to holder of 1st |
138 if (resolved_klass == NULL) { // 2nd argument defaults to holder of 1st |
139 resolved_klass = resolved_method_holder; |
139 resolved_klass = resolved_method_holder; |
140 } |
140 } |
141 _resolved_klass = resolved_klass; |
141 _resolved_klass = resolved_klass; |
142 _selected_klass = resolved_klass; |
142 _selected_klass = resolved_klass; |
143 _resolved_method = resolved_method; |
143 _resolved_method = methodHandle(THREAD, resolved_method); |
144 _selected_method = resolved_method; |
144 _selected_method = methodHandle(THREAD, resolved_method); |
145 // classify: |
145 // classify: |
146 CallKind kind = CallInfo::unknown_kind; |
146 CallKind kind = CallInfo::unknown_kind; |
147 int index = resolved_method->vtable_index(); |
147 int index = resolved_method->vtable_index(); |
148 if (resolved_method->can_be_statically_bound()) { |
148 if (resolved_method->can_be_statically_bound()) { |
149 kind = CallInfo::direct_call; |
149 kind = CallInfo::direct_call; |
151 // Could be an Object method inherited into an interface, but still a vtable call. |
151 // Could be an Object method inherited into an interface, but still a vtable call. |
152 kind = CallInfo::vtable_call; |
152 kind = CallInfo::vtable_call; |
153 } else if (!resolved_klass->is_interface()) { |
153 } else if (!resolved_klass->is_interface()) { |
154 // A default or miranda method. Compute the vtable index. |
154 // A default or miranda method. Compute the vtable index. |
155 index = LinkResolver::vtable_index_of_interface_method(resolved_klass, |
155 index = LinkResolver::vtable_index_of_interface_method(resolved_klass, |
156 resolved_method); |
156 _resolved_method); |
157 assert(index >= 0 , "we should have valid vtable index at this point"); |
157 assert(index >= 0 , "we should have valid vtable index at this point"); |
158 |
158 |
159 kind = CallInfo::vtable_call; |
159 kind = CallInfo::vtable_call; |
160 } else if (resolved_method->has_vtable_index()) { |
160 } else if (resolved_method->has_vtable_index()) { |
161 // Can occur if an interface redeclares a method of Object. |
161 // Can occur if an interface redeclares a method of Object. |
187 |
187 |
188 DEBUG_ONLY(verify()); |
188 DEBUG_ONLY(verify()); |
189 } |
189 } |
190 |
190 |
191 void CallInfo::set_resolved_method_name(TRAPS) { |
191 void CallInfo::set_resolved_method_name(TRAPS) { |
192 Method* m = _resolved_method(); |
192 assert(_resolved_method() != NULL, "Should already have a Method*"); |
193 assert(m != NULL, "Should already have a Method*"); |
193 oop rmethod_name = java_lang_invoke_ResolvedMethodName::find_resolved_method(_resolved_method, CHECK); |
194 oop rmethod_name = java_lang_invoke_ResolvedMethodName::find_resolved_method(m, CHECK); |
|
195 _resolved_method_name = Handle(THREAD, rmethod_name); |
194 _resolved_method_name = Handle(THREAD, rmethod_name); |
196 } |
195 } |
197 |
196 |
198 #ifdef ASSERT |
197 #ifdef ASSERT |
199 void CallInfo::verify() { |
198 void CallInfo::verify() { |
379 return result; |
378 return result; |
380 } |
379 } |
381 |
380 |
382 // returns first instance method |
381 // returns first instance method |
383 // Looks up method in classes, then looks up local default methods |
382 // Looks up method in classes, then looks up local default methods |
384 methodHandle LinkResolver::lookup_instance_method_in_klasses(Klass* klass, |
383 Method* LinkResolver::lookup_instance_method_in_klasses(Klass* klass, |
385 Symbol* name, |
384 Symbol* name, |
386 Symbol* signature, |
385 Symbol* signature, |
387 Klass::PrivateLookupMode private_mode, TRAPS) { |
386 Klass::PrivateLookupMode private_mode, TRAPS) { |
388 Method* result = klass->uncached_lookup_method(name, signature, Klass::find_overpass, private_mode); |
387 Method* result = klass->uncached_lookup_method(name, signature, Klass::find_overpass, private_mode); |
389 |
388 |
390 while (result != NULL && result->is_static() && result->method_holder()->super() != NULL) { |
389 while (result != NULL && result->is_static() && result->method_holder()->super() != NULL) { |
391 Klass* super_klass = result->method_holder()->super(); |
390 Klass* super_klass = result->method_holder()->super(); |
392 result = super_klass->uncached_lookup_method(name, signature, Klass::find_overpass, private_mode); |
391 result = super_klass->uncached_lookup_method(name, signature, Klass::find_overpass, private_mode); |
393 } |
392 } |
394 |
393 |
395 if (klass->is_array_klass()) { |
394 if (klass->is_array_klass()) { |
396 // Only consider klass and super klass for arrays |
395 // Only consider klass and super klass for arrays |
397 return methodHandle(THREAD, result); |
396 return result; |
398 } |
397 } |
399 |
398 |
400 if (result == NULL) { |
399 if (result == NULL) { |
401 Array<Method*>* default_methods = InstanceKlass::cast(klass)->default_methods(); |
400 Array<Method*>* default_methods = InstanceKlass::cast(klass)->default_methods(); |
402 if (default_methods != NULL) { |
401 if (default_methods != NULL) { |
403 result = InstanceKlass::find_method(default_methods, name, signature); |
402 result = InstanceKlass::find_method(default_methods, name, signature); |
404 assert(result == NULL || !result->is_static(), "static defaults not allowed"); |
403 assert(result == NULL || !result->is_static(), "static defaults not allowed"); |
405 } |
404 } |
406 } |
405 } |
407 return methodHandle(THREAD, result); |
406 return result; |
408 } |
407 } |
409 |
408 |
410 int LinkResolver::vtable_index_of_interface_method(Klass* klass, |
409 int LinkResolver::vtable_index_of_interface_method(Klass* klass, |
411 const methodHandle& resolved_method) { |
410 const methodHandle& resolved_method) { |
412 |
411 |
439 // interfaces. Function lookup_method_in_klasses() already looked for |
438 // interfaces. Function lookup_method_in_klasses() already looked for |
440 // the method in the default methods table. |
439 // the method in the default methods table. |
441 return ik->lookup_method_in_all_interfaces(cp_info.name(), cp_info.signature(), Klass::skip_defaults); |
440 return ik->lookup_method_in_all_interfaces(cp_info.name(), cp_info.signature(), Klass::skip_defaults); |
442 } |
441 } |
443 |
442 |
444 methodHandle LinkResolver::lookup_polymorphic_method( |
443 Method* LinkResolver::lookup_polymorphic_method(const LinkInfo& link_info, |
445 const LinkInfo& link_info, |
444 Handle *appendix_result_or_null, |
446 Handle *appendix_result_or_null, |
445 TRAPS) { |
447 TRAPS) { |
|
448 Klass* klass = link_info.resolved_klass(); |
446 Klass* klass = link_info.resolved_klass(); |
449 Symbol* name = link_info.name(); |
447 Symbol* name = link_info.name(); |
450 Symbol* full_signature = link_info.signature(); |
448 Symbol* full_signature = link_info.signature(); |
451 |
449 |
452 vmIntrinsics::ID iid = MethodHandles::signature_polymorphic_name_id(name); |
450 vmIntrinsics::ID iid = MethodHandles::signature_polymorphic_name_id(name); |
470 tty->print_cr("lookup_polymorphic_method %s %s => basic %s", |
468 tty->print_cr("lookup_polymorphic_method %s %s => basic %s", |
471 name->as_C_string(), |
469 name->as_C_string(), |
472 full_signature->as_C_string(), |
470 full_signature->as_C_string(), |
473 basic_signature->as_C_string()); |
471 basic_signature->as_C_string()); |
474 } |
472 } |
475 methodHandle result = SystemDictionary::find_method_handle_intrinsic(iid, |
473 Method* result = SystemDictionary::find_method_handle_intrinsic(iid, |
476 basic_signature, |
474 basic_signature, |
477 CHECK_NULL); |
475 CHECK_NULL); |
478 if (result.not_null()) { |
476 if (result != NULL) { |
479 assert(result->is_method_handle_intrinsic(), "MH.invokeBasic or MH.linkTo* intrinsic"); |
477 assert(result->is_method_handle_intrinsic(), "MH.invokeBasic or MH.linkTo* intrinsic"); |
480 assert(result->intrinsic_id() != vmIntrinsics::_invokeGeneric, "wrong place to find this"); |
478 assert(result->intrinsic_id() != vmIntrinsics::_invokeGeneric, "wrong place to find this"); |
481 assert(basic_signature == result->signature(), "predict the result signature"); |
479 assert(basic_signature == result->signature(), "predict the result signature"); |
482 if (TraceMethodHandles) { |
480 if (TraceMethodHandles) { |
483 ttyLocker ttyl; |
481 ttyLocker ttyl; |
518 result->print_on(tty); |
516 result->print_on(tty); |
519 tty->print(" lookup_polymorphic_method => appendix = "); |
517 tty->print(" lookup_polymorphic_method => appendix = "); |
520 if (appendix.is_null()) tty->print_cr("(none)"); |
518 if (appendix.is_null()) tty->print_cr("(none)"); |
521 else appendix->print_on(tty); |
519 else appendix->print_on(tty); |
522 } |
520 } |
523 if (result.not_null()) { |
521 if (result != NULL) { |
524 #ifdef ASSERT |
522 #ifdef ASSERT |
525 ResourceMark rm(THREAD); |
523 ResourceMark rm(THREAD); |
526 |
524 |
527 TempNewSymbol basic_signature = |
525 TempNewSymbol basic_signature = |
528 MethodHandles::lookup_basic_type_signature(full_signature, CHECK_NULL); |
526 MethodHandles::lookup_basic_type_signature(full_signature, CHECK_NULL); |
601 ); |
599 ); |
602 return; |
600 return; |
603 } |
601 } |
604 } |
602 } |
605 |
603 |
606 methodHandle LinkResolver::resolve_method_statically(Bytecodes::Code code, |
604 Method* LinkResolver::resolve_method_statically(Bytecodes::Code code, |
607 const constantPoolHandle& pool, int index, TRAPS) { |
605 const constantPoolHandle& pool, int index, TRAPS) { |
608 // This method is used only |
606 // This method is used only |
609 // (1) in C2 from InlineTree::ok_to_inline (via ciMethod::check_call), |
607 // (1) in C2 from InlineTree::ok_to_inline (via ciMethod::check_call), |
610 // and |
608 // and |
611 // (2) in Bytecode_invoke::static_target |
609 // (2) in Bytecode_invoke::static_target |
612 // It appears to fail when applied to an invokeinterface call site. |
610 // It appears to fail when applied to an invokeinterface call site. |
627 if (pool->has_preresolution() |
625 if (pool->has_preresolution() |
628 || (resolved_klass == SystemDictionary::MethodHandle_klass() && |
626 || (resolved_klass == SystemDictionary::MethodHandle_klass() && |
629 MethodHandles::is_signature_polymorphic_name(resolved_klass, link_info.name()))) { |
627 MethodHandles::is_signature_polymorphic_name(resolved_klass, link_info.name()))) { |
630 Method* result = ConstantPool::method_at_if_loaded(pool, index); |
628 Method* result = ConstantPool::method_at_if_loaded(pool, index); |
631 if (result != NULL) { |
629 if (result != NULL) { |
632 return methodHandle(THREAD, result); |
630 return result; |
633 } |
631 } |
634 } |
632 } |
635 |
633 |
636 if (code == Bytecodes::_invokeinterface) { |
634 if (code == Bytecodes::_invokeinterface) { |
637 return resolve_interface_method(link_info, code, THREAD); |
635 return resolve_interface_method(link_info, code, THREAD); |
712 sel_klass->class_in_module_of_loader(false, true)); |
710 sel_klass->class_in_module_of_loader(false, true)); |
713 THROW_MSG(vmSymbols::java_lang_LinkageError(), ss.as_string()); |
711 THROW_MSG(vmSymbols::java_lang_LinkageError(), ss.as_string()); |
714 } |
712 } |
715 } |
713 } |
716 |
714 |
717 methodHandle LinkResolver::resolve_method(const LinkInfo& link_info, |
715 Method* LinkResolver::resolve_method(const LinkInfo& link_info, |
718 Bytecodes::Code code, TRAPS) { |
716 Bytecodes::Code code, TRAPS) { |
719 |
717 |
720 Handle nested_exception; |
718 Handle nested_exception; |
721 Klass* resolved_klass = link_info.resolved_klass(); |
719 Klass* resolved_klass = link_info.resolved_klass(); |
722 |
720 |
723 // 1. For invokevirtual, cannot call an interface method |
721 // 1. For invokevirtual, cannot call an interface method |
746 if (resolved_method.is_null() && !resolved_klass->is_array_klass()) { // not found in the class hierarchy |
744 if (resolved_method.is_null() && !resolved_klass->is_array_klass()) { // not found in the class hierarchy |
747 resolved_method = methodHandle(THREAD, lookup_method_in_interfaces(link_info)); |
745 resolved_method = methodHandle(THREAD, lookup_method_in_interfaces(link_info)); |
748 |
746 |
749 if (resolved_method.is_null()) { |
747 if (resolved_method.is_null()) { |
750 // JSR 292: see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc |
748 // JSR 292: see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc |
751 resolved_method = lookup_polymorphic_method(link_info, (Handle*)NULL, THREAD); |
749 Method* method = lookup_polymorphic_method(link_info, (Handle*)NULL, THREAD); |
|
750 resolved_method = methodHandle(THREAD, method); |
752 if (HAS_PENDING_EXCEPTION) { |
751 if (HAS_PENDING_EXCEPTION) { |
753 nested_exception = Handle(THREAD, PENDING_EXCEPTION); |
752 nested_exception = Handle(THREAD, PENDING_EXCEPTION); |
754 CLEAR_PENDING_EXCEPTION; |
753 CLEAR_PENDING_EXCEPTION; |
755 } |
754 } |
756 } |
755 } |
781 |
780 |
782 // check loader constraints |
781 // check loader constraints |
783 check_method_loader_constraints(link_info, resolved_method, "method", CHECK_NULL); |
782 check_method_loader_constraints(link_info, resolved_method, "method", CHECK_NULL); |
784 } |
783 } |
785 |
784 |
786 return resolved_method; |
785 return resolved_method(); |
787 } |
786 } |
788 |
787 |
789 static void trace_method_resolution(const char* prefix, |
788 static void trace_method_resolution(const char* prefix, |
790 Klass* klass, |
789 Klass* klass, |
791 Klass* resolved_klass, |
790 Klass* resolved_klass, |
792 const methodHandle& method, |
791 Method* method, |
793 bool logitables, |
792 bool logitables, |
794 int index = -1) { |
793 int index = -1) { |
795 #ifndef PRODUCT |
794 #ifndef PRODUCT |
796 ResourceMark rm; |
795 ResourceMark rm; |
797 Log(itables) logi; |
796 Log(itables) logi; |
890 |
889 |
891 if (log_develop_is_enabled(Trace, itables)) { |
890 if (log_develop_is_enabled(Trace, itables)) { |
892 char buf[200]; |
891 char buf[200]; |
893 jio_snprintf(buf, sizeof(buf), "%s resolved interface method: caller-class:", |
892 jio_snprintf(buf, sizeof(buf), "%s resolved interface method: caller-class:", |
894 Bytecodes::name(code)); |
893 Bytecodes::name(code)); |
895 trace_method_resolution(buf, link_info.current_klass(), resolved_klass, |
894 trace_method_resolution(buf, link_info.current_klass(), resolved_klass, resolved_method(), true); |
896 resolved_method, true); |
895 } |
897 } |
896 |
898 |
897 return resolved_method(); |
899 return resolved_method; |
|
900 } |
898 } |
901 |
899 |
902 //------------------------------------------------------------------------------------------------------------------------ |
900 //------------------------------------------------------------------------------------------------------------------------ |
903 // Field resolution |
901 // Field resolution |
904 |
902 |
997 current_klass->external_name()); |
995 current_klass->external_name()); |
998 THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), ss.as_string()); |
996 THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), ss.as_string()); |
999 } |
997 } |
1000 |
998 |
1001 if (fd.constants()->pool_holder()->major_version() >= 53) { |
999 if (fd.constants()->pool_holder()->major_version() >= 53) { |
1002 methodHandle m = link_info.current_method(); |
1000 Method* m = link_info.current_method(); |
1003 assert(!m.is_null(), "information about the current method must be available for 'put' bytecodes"); |
1001 assert(m != NULL, "information about the current method must be available for 'put' bytecodes"); |
1004 bool is_initialized_static_final_update = (byte == Bytecodes::_putstatic && |
1002 bool is_initialized_static_final_update = (byte == Bytecodes::_putstatic && |
1005 fd.is_static() && |
1003 fd.is_static() && |
1006 !m()->is_static_initializer()); |
1004 !m->is_static_initializer()); |
1007 bool is_initialized_instance_final_update = ((byte == Bytecodes::_putfield || byte == Bytecodes::_nofast_putfield) && |
1005 bool is_initialized_instance_final_update = ((byte == Bytecodes::_putfield || byte == Bytecodes::_nofast_putfield) && |
1008 !fd.is_static() && |
1006 !fd.is_static() && |
1009 !m->is_object_initializer()); |
1007 !m->is_object_initializer()); |
1010 |
1008 |
1011 if (is_initialized_static_final_update || is_initialized_instance_final_update) { |
1009 if (is_initialized_static_final_update || is_initialized_instance_final_update) { |
1012 ss.print("Update to %s final field %s.%s attempted from a different method (%s) than the initializer method %s ", |
1010 ss.print("Update to %s final field %s.%s attempted from a different method (%s) than the initializer method %s ", |
1013 is_static ? "static" : "non-static", resolved_klass->external_name(), fd.name()->as_C_string(), |
1011 is_static ? "static" : "non-static", resolved_klass->external_name(), fd.name()->as_C_string(), |
1014 m()->name()->as_C_string(), |
1012 m->name()->as_C_string(), |
1015 is_static ? "<clinit>" : "<init>"); |
1013 is_static ? "<clinit>" : "<init>"); |
1016 THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), ss.as_string()); |
1014 THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), ss.as_string()); |
1017 } |
1015 } |
1018 } |
1016 } |
1019 } |
1017 } |
1050 |
1048 |
1051 |
1049 |
1052 void LinkResolver::resolve_static_call(CallInfo& result, |
1050 void LinkResolver::resolve_static_call(CallInfo& result, |
1053 const LinkInfo& link_info, |
1051 const LinkInfo& link_info, |
1054 bool initialize_class, TRAPS) { |
1052 bool initialize_class, TRAPS) { |
1055 methodHandle resolved_method = linktime_resolve_static_method(link_info, CHECK); |
1053 Method* resolved_method = linktime_resolve_static_method(link_info, CHECK); |
1056 |
1054 |
1057 // The resolved class can change as a result of this resolution. |
1055 // The resolved class can change as a result of this resolution. |
1058 Klass* resolved_klass = resolved_method->method_holder(); |
1056 Klass* resolved_klass = resolved_method->method_holder(); |
1059 |
1057 |
1060 // Initialize klass (this should only happen if everything is ok) |
1058 // Initialize klass (this should only happen if everything is ok) |
1066 link_info.check_access() ? LinkInfo::needs_access_check : LinkInfo::skip_access_check); |
1064 link_info.check_access() ? LinkInfo::needs_access_check : LinkInfo::skip_access_check); |
1067 resolved_method = linktime_resolve_static_method(new_info, CHECK); |
1065 resolved_method = linktime_resolve_static_method(new_info, CHECK); |
1068 } |
1066 } |
1069 |
1067 |
1070 // setup result |
1068 // setup result |
1071 result.set_static(resolved_klass, resolved_method, CHECK); |
1069 result.set_static(resolved_klass, methodHandle(THREAD, resolved_method), CHECK); |
1072 } |
1070 } |
1073 |
1071 |
1074 // throws linktime exceptions |
1072 // throws linktime exceptions |
1075 methodHandle LinkResolver::linktime_resolve_static_method(const LinkInfo& link_info, TRAPS) { |
1073 Method* LinkResolver::linktime_resolve_static_method(const LinkInfo& link_info, TRAPS) { |
1076 |
1074 |
1077 Klass* resolved_klass = link_info.resolved_klass(); |
1075 Klass* resolved_klass = link_info.resolved_klass(); |
1078 methodHandle resolved_method; |
1076 Method* resolved_method; |
1079 if (!resolved_klass->is_interface()) { |
1077 if (!resolved_klass->is_interface()) { |
1080 resolved_method = resolve_method(link_info, Bytecodes::_invokestatic, CHECK_NULL); |
1078 resolved_method = resolve_method(link_info, Bytecodes::_invokestatic, CHECK_NULL); |
1081 } else { |
1079 } else { |
1082 resolved_method = resolve_interface_method(link_info, Bytecodes::_invokestatic, CHECK_NULL); |
1080 resolved_method = resolve_interface_method(link_info, Bytecodes::_invokestatic, CHECK_NULL); |
1083 } |
1081 } |
1098 |
1096 |
1099 void LinkResolver::resolve_special_call(CallInfo& result, |
1097 void LinkResolver::resolve_special_call(CallInfo& result, |
1100 Handle recv, |
1098 Handle recv, |
1101 const LinkInfo& link_info, |
1099 const LinkInfo& link_info, |
1102 TRAPS) { |
1100 TRAPS) { |
1103 methodHandle resolved_method = linktime_resolve_special_method(link_info, CHECK); |
1101 Method* resolved_method = linktime_resolve_special_method(link_info, CHECK); |
1104 runtime_resolve_special_method(result, link_info, resolved_method, recv, CHECK); |
1102 runtime_resolve_special_method(result, link_info, methodHandle(THREAD, resolved_method), recv, CHECK); |
1105 } |
1103 } |
1106 |
1104 |
1107 // throws linktime exceptions |
1105 // throws linktime exceptions |
1108 methodHandle LinkResolver::linktime_resolve_special_method(const LinkInfo& link_info, |
1106 Method* LinkResolver::linktime_resolve_special_method(const LinkInfo& link_info, TRAPS) { |
1109 TRAPS) { |
|
1110 |
1107 |
1111 // Invokespecial is called for multiple special reasons: |
1108 // Invokespecial is called for multiple special reasons: |
1112 // <init> |
1109 // <init> |
1113 // local private method invocation, for classes and interfaces |
1110 // local private method invocation, for classes and interfaces |
1114 // superclass.method, which can also resolve to a default method |
1111 // superclass.method, which can also resolve to a default method |
1115 // and the selected method is recalculated relative to the direct superclass |
1112 // and the selected method is recalculated relative to the direct superclass |
1116 // superinterface.method, which explicitly does not check shadowing |
1113 // superinterface.method, which explicitly does not check shadowing |
1117 Klass* resolved_klass = link_info.resolved_klass(); |
1114 Klass* resolved_klass = link_info.resolved_klass(); |
1118 methodHandle resolved_method; |
1115 Method* resolved_method; |
1119 |
1116 |
1120 if (!resolved_klass->is_interface()) { |
1117 if (!resolved_klass->is_interface()) { |
1121 resolved_method = resolve_method(link_info, Bytecodes::_invokespecial, CHECK_NULL); |
1118 resolved_method = resolve_method(link_info, Bytecodes::_invokespecial, CHECK_NULL); |
1122 } else { |
1119 } else { |
1123 resolved_method = resolve_interface_method(link_info, Bytecodes::_invokespecial, CHECK_NULL); |
1120 resolved_method = resolve_interface_method(link_info, Bytecodes::_invokespecial, CHECK_NULL); |
1208 // in super interfaces. |
1205 // in super interfaces. |
1209 if (current_klass->is_subclass_of(resolved_klass) && |
1206 if (current_klass->is_subclass_of(resolved_klass) && |
1210 current_klass != resolved_klass) { |
1207 current_klass != resolved_klass) { |
1211 // Lookup super method |
1208 // Lookup super method |
1212 Klass* super_klass = current_klass->super(); |
1209 Klass* super_klass = current_klass->super(); |
1213 sel_method = lookup_instance_method_in_klasses(super_klass, |
1210 Method* instance_method = lookup_instance_method_in_klasses(super_klass, |
1214 resolved_method->name(), |
1211 resolved_method->name(), |
1215 resolved_method->signature(), |
1212 resolved_method->signature(), |
1216 Klass::find_private, CHECK); |
1213 Klass::find_private, CHECK); |
|
1214 sel_method = methodHandle(THREAD, instance_method); |
|
1215 |
1217 // check if found |
1216 // check if found |
1218 if (sel_method.is_null()) { |
1217 if (sel_method.is_null()) { |
1219 ResourceMark rm(THREAD); |
1218 ResourceMark rm(THREAD); |
1220 stringStream ss; |
1219 stringStream ss; |
1221 ss.print("'"); |
1220 ss.print("'"); |
1270 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), ss.as_string()); |
1269 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), ss.as_string()); |
1271 } |
1270 } |
1272 |
1271 |
1273 if (log_develop_is_enabled(Trace, itables)) { |
1272 if (log_develop_is_enabled(Trace, itables)) { |
1274 trace_method_resolution("invokespecial selected method: resolved-class:", |
1273 trace_method_resolution("invokespecial selected method: resolved-class:", |
1275 resolved_klass, resolved_klass, sel_method, true); |
1274 resolved_klass, resolved_klass, sel_method(), true); |
1276 } |
1275 } |
1277 |
1276 |
1278 // setup result |
1277 // setup result |
1279 result.set_static(resolved_klass, sel_method, CHECK); |
1278 result.set_static(resolved_klass, sel_method, CHECK); |
1280 } |
1279 } |
1281 |
1280 |
1282 void LinkResolver::resolve_virtual_call(CallInfo& result, Handle recv, Klass* receiver_klass, |
1281 void LinkResolver::resolve_virtual_call(CallInfo& result, Handle recv, Klass* receiver_klass, |
1283 const LinkInfo& link_info, |
1282 const LinkInfo& link_info, |
1284 bool check_null_and_abstract, TRAPS) { |
1283 bool check_null_and_abstract, TRAPS) { |
1285 methodHandle resolved_method = linktime_resolve_virtual_method(link_info, CHECK); |
1284 Method* resolved_method = linktime_resolve_virtual_method(link_info, CHECK); |
1286 runtime_resolve_virtual_method(result, resolved_method, |
1285 runtime_resolve_virtual_method(result, methodHandle(THREAD, resolved_method), |
1287 link_info.resolved_klass(), |
1286 link_info.resolved_klass(), |
1288 recv, receiver_klass, |
1287 recv, receiver_klass, |
1289 check_null_and_abstract, CHECK); |
1288 check_null_and_abstract, CHECK); |
1290 } |
1289 } |
1291 |
1290 |
1292 // throws linktime exceptions |
1291 // throws linktime exceptions |
1293 methodHandle LinkResolver::linktime_resolve_virtual_method(const LinkInfo& link_info, |
1292 Method* LinkResolver::linktime_resolve_virtual_method(const LinkInfo& link_info, |
1294 TRAPS) { |
1293 TRAPS) { |
1295 // normal method resolution |
1294 // normal method resolution |
1296 methodHandle resolved_method = resolve_method(link_info, Bytecodes::_invokevirtual, CHECK_NULL); |
1295 Method* resolved_method = resolve_method(link_info, Bytecodes::_invokevirtual, CHECK_NULL); |
1297 |
1296 |
1298 assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier"); |
1297 assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier"); |
1299 assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier"); |
1298 assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier"); |
1300 |
1299 |
1301 // check if private interface method |
1300 // check if private interface method |
1390 throw_abstract_method_error(resolved_method, selected_method, recv_klass, CHECK); |
1389 throw_abstract_method_error(resolved_method, selected_method, recv_klass, CHECK); |
1391 } |
1390 } |
1392 |
1391 |
1393 if (log_develop_is_enabled(Trace, vtables)) { |
1392 if (log_develop_is_enabled(Trace, vtables)) { |
1394 trace_method_resolution("invokevirtual selected method: receiver-class:", |
1393 trace_method_resolution("invokevirtual selected method: receiver-class:", |
1395 recv_klass, resolved_klass, selected_method, |
1394 recv_klass, resolved_klass, selected_method(), |
1396 false, vtable_index); |
1395 false, vtable_index); |
1397 } |
1396 } |
1398 // setup result |
1397 // setup result |
1399 result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK); |
1398 result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK); |
1400 } |
1399 } |
1401 |
1400 |
1402 void LinkResolver::resolve_interface_call(CallInfo& result, Handle recv, Klass* recv_klass, |
1401 void LinkResolver::resolve_interface_call(CallInfo& result, Handle recv, Klass* recv_klass, |
1403 const LinkInfo& link_info, |
1402 const LinkInfo& link_info, |
1404 bool check_null_and_abstract, TRAPS) { |
1403 bool check_null_and_abstract, TRAPS) { |
1405 // throws linktime exceptions |
1404 // throws linktime exceptions |
1406 methodHandle resolved_method = linktime_resolve_interface_method(link_info, CHECK); |
1405 Method* resolved_method = linktime_resolve_interface_method(link_info, CHECK); |
1407 runtime_resolve_interface_method(result, resolved_method,link_info.resolved_klass(), |
1406 methodHandle mh(THREAD, resolved_method); |
|
1407 runtime_resolve_interface_method(result, mh, link_info.resolved_klass(), |
1408 recv, recv_klass, check_null_and_abstract, CHECK); |
1408 recv, recv_klass, check_null_and_abstract, CHECK); |
1409 } |
1409 } |
1410 |
1410 |
1411 methodHandle LinkResolver::linktime_resolve_interface_method(const LinkInfo& link_info, |
1411 Method* LinkResolver::linktime_resolve_interface_method(const LinkInfo& link_info, |
1412 TRAPS) { |
1412 TRAPS) { |
1413 // normal interface method resolution |
1413 // normal interface method resolution |
1414 methodHandle resolved_method = resolve_interface_method(link_info, Bytecodes::_invokeinterface, CHECK_NULL); |
1414 Method* resolved_method = resolve_interface_method(link_info, Bytecodes::_invokeinterface, CHECK_NULL); |
1415 assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier"); |
1415 assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier"); |
1416 assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier"); |
1416 assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier"); |
1417 |
1417 |
1418 return resolved_method; |
1418 return resolved_method; |
1419 } |
1419 } |
1447 if (!resolved_method()->is_private()) { |
1447 if (!resolved_method()->is_private()) { |
1448 // do lookup based on receiver klass |
1448 // do lookup based on receiver klass |
1449 // This search must match the linktime preparation search for itable initialization |
1449 // This search must match the linktime preparation search for itable initialization |
1450 // to correctly enforce loader constraints for interface method inheritance. |
1450 // to correctly enforce loader constraints for interface method inheritance. |
1451 // Private methods are skipped as the resolved method was not private. |
1451 // Private methods are skipped as the resolved method was not private. |
1452 selected_method = lookup_instance_method_in_klasses(recv_klass, |
1452 Method* method = lookup_instance_method_in_klasses(recv_klass, |
1453 resolved_method->name(), |
1453 resolved_method->name(), |
1454 resolved_method->signature(), |
1454 resolved_method->signature(), |
1455 Klass::skip_private, CHECK); |
1455 Klass::skip_private, CHECK); |
|
1456 selected_method = methodHandle(THREAD, method); |
1456 |
1457 |
1457 if (selected_method.is_null() && !check_null_and_abstract) { |
1458 if (selected_method.is_null() && !check_null_and_abstract) { |
1458 // In theory this is a harmless placeholder value, but |
1459 // In theory this is a harmless placeholder value, but |
1459 // in practice leaving in null affects the nsk default method tests. |
1460 // in practice leaving in null affects the nsk default method tests. |
1460 // This needs further study. |
1461 // This needs further study. |
1481 } |
1482 } |
1482 } |
1483 } |
1483 |
1484 |
1484 if (log_develop_is_enabled(Trace, itables)) { |
1485 if (log_develop_is_enabled(Trace, itables)) { |
1485 trace_method_resolution("invokeinterface selected method: receiver-class:", |
1486 trace_method_resolution("invokeinterface selected method: receiver-class:", |
1486 recv_klass, resolved_klass, selected_method, true); |
1487 recv_klass, resolved_klass, selected_method(), true); |
1487 } |
1488 } |
1488 // setup result |
1489 // setup result |
1489 if (resolved_method->has_vtable_index()) { |
1490 if (resolved_method->has_vtable_index()) { |
1490 int vtable_index = resolved_method->vtable_index(); |
1491 int vtable_index = resolved_method->vtable_index(); |
1491 log_develop_trace(itables)(" -- vtable index: %d", vtable_index); |
1492 log_develop_trace(itables)(" -- vtable index: %d", vtable_index); |
1507 result.set_virtual(resolved_klass, resolved_klass, resolved_method, resolved_method, index, CHECK); |
1508 result.set_virtual(resolved_klass, resolved_klass, resolved_method, resolved_method, index, CHECK); |
1508 } |
1509 } |
1509 } |
1510 } |
1510 |
1511 |
1511 |
1512 |
1512 methodHandle LinkResolver::linktime_resolve_interface_method_or_null( |
1513 Method* LinkResolver::linktime_resolve_interface_method_or_null( |
1513 const LinkInfo& link_info) { |
1514 const LinkInfo& link_info) { |
1514 EXCEPTION_MARK; |
1515 EXCEPTION_MARK; |
1515 methodHandle method_result = linktime_resolve_interface_method(link_info, THREAD); |
1516 Method* method_result = linktime_resolve_interface_method(link_info, THREAD); |
1516 if (HAS_PENDING_EXCEPTION) { |
1517 if (HAS_PENDING_EXCEPTION) { |
1517 CLEAR_PENDING_EXCEPTION; |
1518 CLEAR_PENDING_EXCEPTION; |
1518 return methodHandle(); |
1519 return NULL; |
1519 } else { |
1520 } else { |
1520 return method_result; |
1521 return method_result; |
1521 } |
1522 } |
1522 } |
1523 } |
1523 |
1524 |
1524 methodHandle LinkResolver::linktime_resolve_virtual_method_or_null( |
1525 Method* LinkResolver::linktime_resolve_virtual_method_or_null( |
1525 const LinkInfo& link_info) { |
1526 const LinkInfo& link_info) { |
1526 EXCEPTION_MARK; |
1527 EXCEPTION_MARK; |
1527 methodHandle method_result = linktime_resolve_virtual_method(link_info, THREAD); |
1528 Method* method_result = linktime_resolve_virtual_method(link_info, THREAD); |
1528 if (HAS_PENDING_EXCEPTION) { |
1529 if (HAS_PENDING_EXCEPTION) { |
1529 CLEAR_PENDING_EXCEPTION; |
1530 CLEAR_PENDING_EXCEPTION; |
1530 return methodHandle(); |
1531 return NULL; |
1531 } else { |
1532 } else { |
1532 return method_result; |
1533 return method_result; |
1533 } |
1534 } |
1534 } |
1535 } |
1535 |
1536 |
1536 methodHandle LinkResolver::resolve_virtual_call_or_null( |
1537 Method* LinkResolver::resolve_virtual_call_or_null( |
1537 Klass* receiver_klass, |
1538 Klass* receiver_klass, |
1538 const LinkInfo& link_info) { |
1539 const LinkInfo& link_info) { |
1539 EXCEPTION_MARK; |
1540 EXCEPTION_MARK; |
1540 CallInfo info; |
1541 CallInfo info; |
1541 resolve_virtual_call(info, Handle(), receiver_klass, link_info, false, THREAD); |
1542 resolve_virtual_call(info, Handle(), receiver_klass, link_info, false, THREAD); |
1542 if (HAS_PENDING_EXCEPTION) { |
1543 if (HAS_PENDING_EXCEPTION) { |
1543 CLEAR_PENDING_EXCEPTION; |
1544 CLEAR_PENDING_EXCEPTION; |
1544 return methodHandle(); |
1545 return NULL; |
1545 } |
1546 } |
1546 return info.selected_method(); |
1547 return info.selected_method(); |
1547 } |
1548 } |
1548 |
1549 |
1549 methodHandle LinkResolver::resolve_interface_call_or_null( |
1550 Method* LinkResolver::resolve_interface_call_or_null( |
1550 Klass* receiver_klass, |
1551 Klass* receiver_klass, |
1551 const LinkInfo& link_info) { |
1552 const LinkInfo& link_info) { |
1552 EXCEPTION_MARK; |
1553 EXCEPTION_MARK; |
1553 CallInfo info; |
1554 CallInfo info; |
1554 resolve_interface_call(info, Handle(), receiver_klass, link_info, false, THREAD); |
1555 resolve_interface_call(info, Handle(), receiver_klass, link_info, false, THREAD); |
1555 if (HAS_PENDING_EXCEPTION) { |
1556 if (HAS_PENDING_EXCEPTION) { |
1556 CLEAR_PENDING_EXCEPTION; |
1557 CLEAR_PENDING_EXCEPTION; |
1557 return methodHandle(); |
1558 return NULL; |
1558 } |
1559 } |
1559 return info.selected_method(); |
1560 return info.selected_method(); |
1560 } |
1561 } |
1561 |
1562 |
1562 int LinkResolver::resolve_virtual_vtable_index(Klass* receiver_klass, |
1563 int LinkResolver::resolve_virtual_vtable_index(Klass* receiver_klass, |
1570 return Method::invalid_vtable_index; |
1571 return Method::invalid_vtable_index; |
1571 } |
1572 } |
1572 return info.vtable_index(); |
1573 return info.vtable_index(); |
1573 } |
1574 } |
1574 |
1575 |
1575 methodHandle LinkResolver::resolve_static_call_or_null(const LinkInfo& link_info) { |
1576 Method* LinkResolver::resolve_static_call_or_null(const LinkInfo& link_info) { |
1576 EXCEPTION_MARK; |
1577 EXCEPTION_MARK; |
1577 CallInfo info; |
1578 CallInfo info; |
1578 resolve_static_call(info, link_info, /*initialize_class*/false, THREAD); |
1579 resolve_static_call(info, link_info, /*initialize_class*/false, THREAD); |
1579 if (HAS_PENDING_EXCEPTION) { |
1580 if (HAS_PENDING_EXCEPTION) { |
1580 CLEAR_PENDING_EXCEPTION; |
1581 CLEAR_PENDING_EXCEPTION; |
1581 return methodHandle(); |
1582 return NULL; |
1582 } |
1583 } |
1583 return info.selected_method(); |
1584 return info.selected_method(); |
1584 } |
1585 } |
1585 |
1586 |
1586 methodHandle LinkResolver::resolve_special_call_or_null(const LinkInfo& link_info) { |
1587 Method* LinkResolver::resolve_special_call_or_null(const LinkInfo& link_info) { |
1587 EXCEPTION_MARK; |
1588 EXCEPTION_MARK; |
1588 CallInfo info; |
1589 CallInfo info; |
1589 resolve_special_call(info, Handle(), link_info, THREAD); |
1590 resolve_special_call(info, Handle(), link_info, THREAD); |
1590 if (HAS_PENDING_EXCEPTION) { |
1591 if (HAS_PENDING_EXCEPTION) { |
1591 CLEAR_PENDING_EXCEPTION; |
1592 CLEAR_PENDING_EXCEPTION; |
1592 return methodHandle(); |
1593 return NULL; |
1593 } |
1594 } |
1594 return info.selected_method(); |
1595 return info.selected_method(); |
1595 } |
1596 } |
1596 |
1597 |
1597 |
1598 |
1688 Klass* resolved_klass = link_info.resolved_klass(); |
1689 Klass* resolved_klass = link_info.resolved_klass(); |
1689 assert(resolved_klass == SystemDictionary::MethodHandle_klass() || |
1690 assert(resolved_klass == SystemDictionary::MethodHandle_klass() || |
1690 resolved_klass == SystemDictionary::VarHandle_klass(), ""); |
1691 resolved_klass == SystemDictionary::VarHandle_klass(), ""); |
1691 assert(MethodHandles::is_signature_polymorphic_name(link_info.name()), ""); |
1692 assert(MethodHandles::is_signature_polymorphic_name(link_info.name()), ""); |
1692 Handle resolved_appendix; |
1693 Handle resolved_appendix; |
1693 methodHandle resolved_method = lookup_polymorphic_method(link_info, &resolved_appendix, CHECK); |
1694 Method* resolved_method = lookup_polymorphic_method(link_info, &resolved_appendix, CHECK); |
1694 result.set_handle(resolved_klass, resolved_method, resolved_appendix, CHECK); |
1695 result.set_handle(resolved_klass, methodHandle(THREAD, resolved_method), resolved_appendix, CHECK); |
1695 } |
1696 } |
1696 |
1697 |
1697 void LinkResolver::resolve_invokedynamic(CallInfo& result, const constantPoolHandle& pool, int indy_index, TRAPS) { |
1698 void LinkResolver::resolve_invokedynamic(CallInfo& result, const constantPoolHandle& pool, int indy_index, TRAPS) { |
1698 ConstantPoolCacheEntry* cpce = pool->invokedynamic_cp_cache_entry_at(indy_index); |
1699 ConstantPoolCacheEntry* cpce = pool->invokedynamic_cp_cache_entry_at(indy_index); |
1699 int pool_index = cpce->constant_pool_index(); |
1700 int pool_index = cpce->constant_pool_index(); |