< prev index next >

src/hotspot/share/prims/methodHandles.cpp

Print this page
rev 55090 : secret-sfac


 280       m_klass = m_klass_non_interface;
 281     }
 282     if (TraceInvokeDynamic) {
 283       ttyLocker ttyl;
 284       ResourceMark rm;
 285       tty->print_cr("memberName: invokevirtual method_holder::method: %s, receiver: %s, vtableindex: %d, access_flags:",
 286             Method::name_and_sig_as_C_string(m->method_holder(), m->name(), m->signature()),
 287             m_klass->internal_name(), vmindex);
 288        m->access_flags().print_on(tty);
 289        if (m->is_default_method()) {
 290          tty->print("default");
 291        }
 292        tty->cr();
 293     }
 294     break;
 295 
 296   case CallInfo::direct_call:
 297     vmindex = Method::nonvirtual_vtable_index;
 298     if (m->is_static()) {
 299       flags |= IS_METHOD      | (JVM_REF_invokeStatic  << REFERENCE_KIND_SHIFT);
 300     } else if (m->is_initializer()) {
 301       flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
 302     } else {
 303       // "special" reflects that this is a direct call, not that it
 304       // necessarily originates from an invokespecial. We can also do
 305       // direct calls for private and/or final non-static methods.
 306       flags |= IS_METHOD      | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
 307     }
 308     break;
 309 
 310   default:  assert(false, "bad CallInfo");  return NULL;
 311   }
 312 
 313   // @CallerSensitive annotation detected
 314   if (m->caller_sensitive()) {
 315     flags |= CALLER_SENSITIVE;
 316   }
 317 
 318   Handle resolved_method = info.resolved_method_name();
 319   assert(java_lang_invoke_ResolvedMethodName::vmtarget(resolved_method()) == m() || m->is_old(),
 320          "Should not change after link resolution");


 822           }
 823           return empty;
 824         }
 825       }
 826       if (result.resolved_appendix().not_null()) {
 827         // The resolved MemberName must not be accompanied by an appendix argument,
 828         // since there is no way to bind this value into the MemberName.
 829         // Caller is responsible to prevent this from happening.
 830         THROW_MSG_(vmSymbols::java_lang_InternalError(), "appendix", empty);
 831       }
 832       result.set_resolved_method_name(CHECK_(empty));
 833       oop mname2 = init_method_MemberName(mname, result);
 834       return Handle(THREAD, mname2);
 835     }
 836   case IS_CONSTRUCTOR:
 837     {
 838       CallInfo result;
 839       LinkInfo link_info(defc, name, type, caller, access_check);
 840       {
 841         assert(!HAS_PENDING_EXCEPTION, "");
 842         if (name == vmSymbols::object_initializer_name()) {


 843           LinkResolver::resolve_special_call(result, Handle(), link_info, THREAD);
 844         } else {
 845           break;                // will throw after end of switch

 846         }
 847         if (HAS_PENDING_EXCEPTION) {
 848           if (speculative_resolve) {
 849             CLEAR_PENDING_EXCEPTION;
 850           }
 851           return empty;
 852         }
 853       }
 854       assert(result.is_statically_bound(), "");
 855       result.set_resolved_method_name(CHECK_(empty));
 856       oop mname2 = init_method_MemberName(mname, result);
 857       return Handle(THREAD, mname2);
 858     }
 859   case IS_FIELD:
 860     {
 861       fieldDescriptor result; // find_field initializes fd if found
 862       {
 863         assert(!HAS_PENDING_EXCEPTION, "");
 864         LinkInfo link_info(defc, name, type, caller, LinkInfo::skip_access_check);
 865         LinkResolver::resolve_field(result, link_info, Bytecodes::_nop, false, THREAD);


1002       if (rskip > 0) {
1003         --rskip;
1004       } else if (rfill < rlimit) {
1005         Handle result(thread, results->obj_at(rfill++));
1006         if (!java_lang_invoke_MemberName::is_instance(result()))
1007           return -99;  // caller bug!
1008         oop saved = MethodHandles::init_field_MemberName(result, st.field_descriptor());
1009         if (!oopDesc::equals(saved, result()))
1010           results->obj_at_put(rfill-1, saved);  // show saved instance to user
1011       } else if (++overflow >= overflow_limit) {
1012         match_flags = 0; break; // got tired of looking at overflow
1013       }
1014     }
1015   }
1016 
1017   if ((match_flags & (IS_METHOD | IS_CONSTRUCTOR)) != 0) {
1018     // watch out for these guys:
1019     Symbol* init_name   = vmSymbols::object_initializer_name();
1020     Symbol* clinit_name = vmSymbols::class_initializer_name();
1021     if (name == clinit_name)  clinit_name = NULL; // hack for exposing <clinit>
1022     bool negate_name_test = false;
1023     // fix name so that it captures the intention of IS_CONSTRUCTOR
1024     if (!(match_flags & IS_METHOD)) {
1025       // constructors only
1026       if (name == NULL) {
1027         name = init_name;
1028       } else if (name != init_name) {
1029         return 0;               // no constructors of this method name
1030       }

1031     } else if (!(match_flags & IS_CONSTRUCTOR)) {
1032       // methods only
1033       if (name == NULL) {
1034         name = init_name;
1035         negate_name_test = true; // if we see the name, we *omit* the entry
1036       } else if (name == init_name) {
1037         return 0;               // no methods of this constructor name
1038       }
1039     } else {
1040       // caller will accept either sort; no need to adjust name
1041     }
1042     InstanceKlass* ik = InstanceKlass::cast(k);
1043     for (MethodStream st(ik, local_only, !search_intfc); !st.eos(); st.next()) {
1044       Method* m = st.method();
1045       Symbol* m_name = m->name();
1046       if (m_name == clinit_name)
1047         continue;
1048       if (name != NULL && ((m_name != name) ^ negate_name_test))
1049           continue;
1050       if (sig != NULL && m->signature() != sig)
1051         continue;




1052       // passed the filters
1053       if (rskip > 0) {
1054         --rskip;
1055       } else if (rfill < rlimit) {
1056         Handle result(thread, results->obj_at(rfill++));
1057         if (!java_lang_invoke_MemberName::is_instance(result()))
1058           return -99;  // caller bug!
1059         CallInfo info(m, NULL, CHECK_0);
1060         oop saved = MethodHandles::init_method_MemberName(result, info);
1061         if (!oopDesc::equals(saved, result()))
1062           results->obj_at_put(rfill-1, saved);  // show saved instance to user
1063       } else if (++overflow >= overflow_limit) {
1064         match_flags = 0; break; // got tired of looking at overflow
1065       }
1066     }
1067   }
1068 
1069   // return number of elements we at leasted wanted to initialize
1070   return rfill + overflow;
1071 }




 280       m_klass = m_klass_non_interface;
 281     }
 282     if (TraceInvokeDynamic) {
 283       ttyLocker ttyl;
 284       ResourceMark rm;
 285       tty->print_cr("memberName: invokevirtual method_holder::method: %s, receiver: %s, vtableindex: %d, access_flags:",
 286             Method::name_and_sig_as_C_string(m->method_holder(), m->name(), m->signature()),
 287             m_klass->internal_name(), vmindex);
 288        m->access_flags().print_on(tty);
 289        if (m->is_default_method()) {
 290          tty->print("default");
 291        }
 292        tty->cr();
 293     }
 294     break;
 295 
 296   case CallInfo::direct_call:
 297     vmindex = Method::nonvirtual_vtable_index;
 298     if (m->is_static()) {
 299       flags |= IS_METHOD      | (JVM_REF_invokeStatic  << REFERENCE_KIND_SHIFT);
 300     } else if (m->is_object_constructor()) {
 301       flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
 302     } else {
 303       // "special" reflects that this is a direct call, not that it
 304       // necessarily originates from an invokespecial. We can also do
 305       // direct calls for private and/or final non-static methods.
 306       flags |= IS_METHOD      | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
 307     }
 308     break;
 309 
 310   default:  assert(false, "bad CallInfo");  return NULL;
 311   }
 312 
 313   // @CallerSensitive annotation detected
 314   if (m->caller_sensitive()) {
 315     flags |= CALLER_SENSITIVE;
 316   }
 317 
 318   Handle resolved_method = info.resolved_method_name();
 319   assert(java_lang_invoke_ResolvedMethodName::vmtarget(resolved_method()) == m() || m->is_old(),
 320          "Should not change after link resolution");


 822           }
 823           return empty;
 824         }
 825       }
 826       if (result.resolved_appendix().not_null()) {
 827         // The resolved MemberName must not be accompanied by an appendix argument,
 828         // since there is no way to bind this value into the MemberName.
 829         // Caller is responsible to prevent this from happening.
 830         THROW_MSG_(vmSymbols::java_lang_InternalError(), "appendix", empty);
 831       }
 832       result.set_resolved_method_name(CHECK_(empty));
 833       oop mname2 = init_method_MemberName(mname, result);
 834       return Handle(THREAD, mname2);
 835     }
 836   case IS_CONSTRUCTOR:
 837     {
 838       CallInfo result;
 839       LinkInfo link_info(defc, name, type, caller, access_check);
 840       {
 841         assert(!HAS_PENDING_EXCEPTION, "");
 842         if (name != vmSymbols::object_initializer_name()) {
 843           break;                // will throw after end of switch
 844         } else if (type->is_void_method_signature()) {
 845           LinkResolver::resolve_special_call(result, Handle(), link_info, THREAD);
 846         } else {
 847           // LinkageError unless  it returns something reasonable
 848           LinkResolver::resolve_static_call(result, link_info, false, THREAD);
 849         }
 850         if (HAS_PENDING_EXCEPTION) {
 851           if (speculative_resolve) {
 852             CLEAR_PENDING_EXCEPTION;
 853           }
 854           return empty;
 855         }
 856       }
 857       assert(result.is_statically_bound(), "");
 858       result.set_resolved_method_name(CHECK_(empty));
 859       oop mname2 = init_method_MemberName(mname, result);
 860       return Handle(THREAD, mname2);
 861     }
 862   case IS_FIELD:
 863     {
 864       fieldDescriptor result; // find_field initializes fd if found
 865       {
 866         assert(!HAS_PENDING_EXCEPTION, "");
 867         LinkInfo link_info(defc, name, type, caller, LinkInfo::skip_access_check);
 868         LinkResolver::resolve_field(result, link_info, Bytecodes::_nop, false, THREAD);


1005       if (rskip > 0) {
1006         --rskip;
1007       } else if (rfill < rlimit) {
1008         Handle result(thread, results->obj_at(rfill++));
1009         if (!java_lang_invoke_MemberName::is_instance(result()))
1010           return -99;  // caller bug!
1011         oop saved = MethodHandles::init_field_MemberName(result, st.field_descriptor());
1012         if (!oopDesc::equals(saved, result()))
1013           results->obj_at_put(rfill-1, saved);  // show saved instance to user
1014       } else if (++overflow >= overflow_limit) {
1015         match_flags = 0; break; // got tired of looking at overflow
1016       }
1017     }
1018   }
1019 
1020   if ((match_flags & (IS_METHOD | IS_CONSTRUCTOR)) != 0) {
1021     // watch out for these guys:
1022     Symbol* init_name   = vmSymbols::object_initializer_name();
1023     Symbol* clinit_name = vmSymbols::class_initializer_name();
1024     if (name == clinit_name)  clinit_name = NULL; // hack for exposing <clinit>
1025     bool ctor_ok = true, sfac_ok = true;
1026     // fix name so that it captures the intention of IS_CONSTRUCTOR
1027     if (!(match_flags & IS_METHOD)) {
1028       // constructors only
1029       if (name == NULL) {
1030         name = init_name;
1031       } else if (name != init_name) {
1032         return 0;               // no constructors of this method name
1033       }
1034       sfac_ok = false;
1035     } else if (!(match_flags & IS_CONSTRUCTOR)) {
1036       // methods only
1037       ctor_ok = false;  // but sfac_ok is true, so we might find <init>





1038     } else {
1039       // caller will accept either sort; no need to adjust name
1040     }
1041     InstanceKlass* ik = InstanceKlass::cast(k);
1042     for (MethodStream st(ik, local_only, !search_intfc); !st.eos(); st.next()) {
1043       Method* m = st.method();
1044       Symbol* m_name = m->name();
1045       if (m_name == clinit_name)
1046         continue;
1047       if (name != NULL && m_name != name)
1048           continue;
1049       if (sig != NULL && m->signature() != sig)
1050         continue;
1051       if (m_name == init_name) {  // might be either ctor or sfac
1052         if (m->is_object_constructor()  && !ctor_ok)  continue;
1053         if (m->is_static_init_factory() && !sfac_ok)  continue;
1054       }
1055       // passed the filters
1056       if (rskip > 0) {
1057         --rskip;
1058       } else if (rfill < rlimit) {
1059         Handle result(thread, results->obj_at(rfill++));
1060         if (!java_lang_invoke_MemberName::is_instance(result()))
1061           return -99;  // caller bug!
1062         CallInfo info(m, NULL, CHECK_0);
1063         oop saved = MethodHandles::init_method_MemberName(result, info);
1064         if (!oopDesc::equals(saved, result()))
1065           results->obj_at_put(rfill-1, saved);  // show saved instance to user
1066       } else if (++overflow >= overflow_limit) {
1067         match_flags = 0; break; // got tired of looking at overflow
1068       }
1069     }
1070   }
1071 
1072   // return number of elements we at leasted wanted to initialize
1073   return rfill + overflow;
1074 }


< prev index next >