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 }