Mercurial > hg > graal-compiler
comparison src/share/vm/runtime/sharedRuntime.cpp @ 2461:758ba0bf7bcc
7012087: JSR 292 Misleading exception message for a non-bound MH for a virtual method
Summary: Improve error message formatting to give more information to user. Also, catch a corner case related to 6930553 and 6844449.
Reviewed-by: kvn
author | jrose |
---|---|
date | Thu, 07 Apr 2011 17:12:21 -0700 |
parents | 38fea01eb669 |
children | 0654ee04b214 2a23b1b5a0a8 |
comparison
equal
deleted
inserted
replaced
2460:ed69575596ac | 2461:758ba0bf7bcc |
---|---|
1698 ? (klassOop)required | 1698 ? (klassOop)required |
1699 : java_lang_Class::as_klassOop(required)); | 1699 : java_lang_Class::as_klassOop(required)); |
1700 message = generate_class_cast_message(objName, targetKlass->external_name()); | 1700 message = generate_class_cast_message(objName, targetKlass->external_name()); |
1701 } else { | 1701 } else { |
1702 // %%% need to get the MethodType string, without messing around too much | 1702 // %%% need to get the MethodType string, without messing around too much |
1703 const char* desc = NULL; | |
1703 // Get a signature from the invoke instruction | 1704 // Get a signature from the invoke instruction |
1704 const char* mhName = "method handle"; | 1705 const char* mhName = "method handle"; |
1705 const char* targetType = "the required signature"; | 1706 const char* targetType = "the required signature"; |
1707 int targetArity = -1, mhArity = -1; | |
1706 vframeStream vfst(thread, true); | 1708 vframeStream vfst(thread, true); |
1707 if (!vfst.at_end()) { | 1709 if (!vfst.at_end()) { |
1708 Bytecode_invoke call(vfst.method(), vfst.bci()); | 1710 Bytecode_invoke call(vfst.method(), vfst.bci()); |
1709 methodHandle target; | 1711 methodHandle target; |
1710 { | 1712 { |
1714 } | 1716 } |
1715 if (target.not_null() | 1717 if (target.not_null() |
1716 && target->is_method_handle_invoke() | 1718 && target->is_method_handle_invoke() |
1717 && required == target->method_handle_type()) { | 1719 && required == target->method_handle_type()) { |
1718 targetType = target->signature()->as_C_string(); | 1720 targetType = target->signature()->as_C_string(); |
1721 targetArity = ArgumentCount(target->signature()).size(); | |
1719 } | 1722 } |
1720 } | 1723 } |
1721 klassOop kignore; int fignore; | 1724 klassOop kignore; int dmf_flags = 0; |
1722 methodOop actual_method = MethodHandles::decode_method(actual, | 1725 methodOop actual_method = MethodHandles::decode_method(actual, kignore, dmf_flags); |
1723 kignore, fignore); | 1726 if ((dmf_flags & ~(MethodHandles::_dmf_has_receiver | |
1727 MethodHandles::_dmf_does_dispatch | | |
1728 MethodHandles::_dmf_from_interface)) != 0) | |
1729 actual_method = NULL; // MH does extra binds, drops, etc. | |
1730 bool has_receiver = ((dmf_flags & MethodHandles::_dmf_has_receiver) != 0); | |
1724 if (actual_method != NULL) { | 1731 if (actual_method != NULL) { |
1725 if (methodOopDesc::is_method_handle_invoke_name(actual_method->name())) | 1732 mhName = actual_method->signature()->as_C_string(); |
1726 mhName = "$"; | 1733 mhArity = ArgumentCount(actual_method->signature()).size(); |
1734 if (!actual_method->is_static()) mhArity += 1; | |
1735 } else if (java_lang_invoke_MethodHandle::is_instance(actual)) { | |
1736 oopDesc* mhType = java_lang_invoke_MethodHandle::type(actual); | |
1737 mhArity = java_lang_invoke_MethodType::ptype_count(mhType); | |
1738 stringStream st; | |
1739 java_lang_invoke_MethodType::print_signature(mhType, &st); | |
1740 mhName = st.as_string(); | |
1741 } | |
1742 if (targetArity != -1 && targetArity != mhArity) { | |
1743 if (has_receiver && targetArity == mhArity-1) | |
1744 desc = " cannot be called without a receiver argument as "; | |
1727 else | 1745 else |
1728 mhName = actual_method->signature()->as_C_string(); | 1746 desc = " cannot be called with a different arity as "; |
1729 if (mhName[0] == '$') | |
1730 mhName = actual_method->signature()->as_C_string(); | |
1731 } | 1747 } |
1732 message = generate_class_cast_message(mhName, targetType, | 1748 message = generate_class_cast_message(mhName, targetType, |
1749 desc != NULL ? desc : | |
1733 " cannot be called as "); | 1750 " cannot be called as "); |
1734 } | 1751 } |
1735 if (TraceMethodHandles) { | 1752 if (TraceMethodHandles) { |
1736 tty->print_cr("WrongMethodType => message=%s", message); | 1753 tty->print_cr("WrongMethodType => message=%s", message); |
1737 } | 1754 } |