276 |
276 |
277 methodOop MethodHandles::decode_methodOop(methodOop m, int& decode_flags_result) { |
277 methodOop MethodHandles::decode_methodOop(methodOop m, int& decode_flags_result) { |
278 assert(m->is_method(), ""); |
278 assert(m->is_method(), ""); |
279 if (m->is_static()) { |
279 if (m->is_static()) { |
280 // check that signature begins '(L' or '([' (not '(I', '()', etc.) |
280 // check that signature begins '(L' or '([' (not '(I', '()', etc.) |
281 symbolOop sig = m->signature(); |
281 Symbol* sig = m->signature(); |
282 BasicType recv_bt = char2type(sig->byte_at(1)); |
282 BasicType recv_bt = char2type(sig->byte_at(1)); |
283 // Note: recv_bt might be T_ILLEGAL if byte_at(2) is ')' |
283 // Note: recv_bt might be T_ILLEGAL if byte_at(2) is ')' |
284 assert(sig->byte_at(0) == '(', "must be method sig"); |
284 assert(sig->byte_at(0) == '(', "must be method sig"); |
285 // if (recv_bt == T_OBJECT || recv_bt == T_ARRAY) |
285 // if (recv_bt == T_OBJECT || recv_bt == T_ARRAY) |
286 // decode_flags_result |= _dmf_has_receiver; |
286 // decode_flags_result |= _dmf_has_receiver; |
436 if (klass != NULL) receiver_limit_result = klass; |
436 if (klass != NULL) receiver_limit_result = klass; |
437 } |
437 } |
438 return m; |
438 return m; |
439 } |
439 } |
440 |
440 |
|
441 // convert the external string or reflective type to an internal signature |
|
442 Symbol* MethodHandles::convert_to_signature(oop type_str, |
|
443 bool polymorphic, |
|
444 TRAPS) { |
|
445 if (java_dyn_MethodType::is_instance(type_str)) { |
|
446 return java_dyn_MethodType::as_signature(type_str, polymorphic, CHECK_NULL); |
|
447 } else if (java_lang_Class::is_instance(type_str)) { |
|
448 return java_lang_Class::as_signature(type_str, false, CHECK_NULL); |
|
449 } else if (java_lang_String::is_instance(type_str)) { |
|
450 if (polymorphic) { |
|
451 return java_lang_String::as_symbol(type_str, CHECK_NULL); |
|
452 } else { |
|
453 return java_lang_String::as_symbol_or_null(type_str); |
|
454 } |
|
455 } else { |
|
456 THROW_MSG_(vmSymbols::java_lang_InternalError(), "unrecognized type", NULL); |
|
457 } |
|
458 } |
|
459 |
441 // An unresolved member name is a mere symbolic reference. |
460 // An unresolved member name is a mere symbolic reference. |
442 // Resolving it plants a vmtarget/vmindex in it, |
461 // Resolving it plants a vmtarget/vmindex in it, |
443 // which refers dirctly to JVM internals. |
462 // which refers dirctly to JVM internals. |
444 void MethodHandles::resolve_MemberName(Handle mname, TRAPS) { |
463 void MethodHandles::resolve_MemberName(Handle mname, TRAPS) { |
445 assert(sun_dyn_MemberName::is_instance(mname()), ""); |
464 assert(sun_dyn_MemberName::is_instance(mname()), ""); |
476 THROW_MSG(vmSymbols::java_lang_InternalError(), "primitive class"); |
495 THROW_MSG(vmSymbols::java_lang_InternalError(), "primitive class"); |
477 } |
496 } |
478 defc->link_class(CHECK); |
497 defc->link_class(CHECK); |
479 |
498 |
480 // convert the external string name to an internal symbol |
499 // convert the external string name to an internal symbol |
481 symbolHandle name(THREAD, java_lang_String::as_symbol_or_null(name_str)); |
500 TempNewSymbol name = java_lang_String::as_symbol_or_null(name_str); |
482 if (name.is_null()) return; // no such name |
501 if (name == NULL) return; // no such name |
483 name_str = NULL; // safety |
502 name_str = NULL; // safety |
484 |
503 |
485 Handle polymorphic_method_type; |
504 Handle polymorphic_method_type; |
486 bool polymorphic_signature = false; |
505 bool polymorphic_signature = false; |
487 if ((flags & ALL_KINDS) == IS_METHOD && |
506 if ((flags & ALL_KINDS) == IS_METHOD && |
488 (defc() == SystemDictionary::MethodHandle_klass() && |
507 (defc() == SystemDictionary::MethodHandle_klass() && |
489 methodOopDesc::is_method_handle_invoke_name(name()))) |
508 methodOopDesc::is_method_handle_invoke_name(name))) |
490 polymorphic_signature = true; |
509 polymorphic_signature = true; |
491 |
510 |
492 // convert the external string or reflective type to an internal signature |
511 // convert the external string or reflective type to an internal signature |
493 symbolHandle type; { |
512 TempNewSymbol type = convert_to_signature(type_str, polymorphic_signature, CHECK); |
494 symbolOop type_sym = NULL; |
513 if (java_dyn_MethodType::is_instance(type_str) && polymorphic_signature) { |
495 if (java_dyn_MethodType::is_instance(type_str)) { |
514 polymorphic_method_type = Handle(THREAD, type_str); //preserve exactly |
496 type_sym = java_dyn_MethodType::as_signature(type_str, polymorphic_signature, CHECK); |
515 } |
497 if (polymorphic_signature) |
516 |
498 polymorphic_method_type = Handle(THREAD, type_str); //preserve exactly |
517 if (type == NULL) return; // no such signature exists in the VM |
499 } else if (java_lang_Class::is_instance(type_str)) { |
|
500 type_sym = java_lang_Class::as_signature(type_str, false, CHECK); |
|
501 } else if (java_lang_String::is_instance(type_str)) { |
|
502 if (polymorphic_signature) { |
|
503 type = java_lang_String::as_symbol(type_str, CHECK); |
|
504 } else { |
|
505 type_sym = java_lang_String::as_symbol_or_null(type_str); |
|
506 } |
|
507 } else { |
|
508 THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized type"); |
|
509 } |
|
510 if (type_sym != NULL) |
|
511 type = symbolHandle(THREAD, type_sym); |
|
512 } |
|
513 if (type.is_null()) return; // no such signature exists in the VM |
|
514 type_str = NULL; // safety |
518 type_str = NULL; // safety |
515 |
519 |
516 // Time to do the lookup. |
520 // Time to do the lookup. |
517 switch (flags & ALL_KINDS) { |
521 switch (flags & ALL_KINDS) { |
518 case IS_METHOD: |
522 case IS_METHOD: |
564 case IS_CONSTRUCTOR: |
568 case IS_CONSTRUCTOR: |
565 { |
569 { |
566 CallInfo result; |
570 CallInfo result; |
567 { |
571 { |
568 EXCEPTION_MARK; |
572 EXCEPTION_MARK; |
569 if (name() == vmSymbols::object_initializer_name()) { |
573 if (name == vmSymbols::object_initializer_name()) { |
570 LinkResolver::resolve_special_call(result, |
574 LinkResolver::resolve_special_call(result, |
571 defc, name, type, KlassHandle(), false, THREAD); |
575 defc, name, type, KlassHandle(), false, THREAD); |
572 } else { |
576 } else { |
573 break; // will throw after end of switch |
577 break; // will throw after end of switch |
574 } |
578 } |
592 } |
596 } |
593 case IS_FIELD: |
597 case IS_FIELD: |
594 { |
598 { |
595 // This is taken from LinkResolver::resolve_field, sans access checks. |
599 // This is taken from LinkResolver::resolve_field, sans access checks. |
596 fieldDescriptor fd; // find_field initializes fd if found |
600 fieldDescriptor fd; // find_field initializes fd if found |
597 KlassHandle sel_klass(THREAD, instanceKlass::cast(defc())->find_field(name(), type(), &fd)); |
601 KlassHandle sel_klass(THREAD, instanceKlass::cast(defc())->find_field(name, type, &fd)); |
598 // check if field exists; i.e., if a klass containing the field def has been selected |
602 // check if field exists; i.e., if a klass containing the field def has been selected |
599 if (sel_klass.is_null()) return; |
603 if (sel_klass.is_null()) return; |
600 oop vmtarget = sel_klass->as_klassOop(); |
604 oop vmtarget = sel_klass->as_klassOop(); |
601 int vmindex = fd.offset(); |
605 int vmindex = fd.offset(); |
602 int mods = (fd.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS); |
606 int mods = (fd.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS); |
723 } |
727 } |
724 THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format"); |
728 THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format"); |
725 } |
729 } |
726 |
730 |
727 int MethodHandles::find_MemberNames(klassOop k, |
731 int MethodHandles::find_MemberNames(klassOop k, |
728 symbolOop name, symbolOop sig, |
732 Symbol* name, Symbol* sig, |
729 int mflags, klassOop caller, |
733 int mflags, klassOop caller, |
730 int skip, objArrayOop results) { |
734 int skip, objArrayOop results) { |
731 DEBUG_ONLY(No_Safepoint_Verifier nsv); |
735 DEBUG_ONLY(No_Safepoint_Verifier nsv); |
732 // this code contains no safepoints! |
736 // this code contains no safepoints! |
733 |
737 |
780 } |
784 } |
781 } |
785 } |
782 |
786 |
783 if ((match_flags & (IS_METHOD | IS_CONSTRUCTOR)) != 0) { |
787 if ((match_flags & (IS_METHOD | IS_CONSTRUCTOR)) != 0) { |
784 // watch out for these guys: |
788 // watch out for these guys: |
785 symbolOop init_name = vmSymbols::object_initializer_name(); |
789 Symbol* init_name = vmSymbols::object_initializer_name(); |
786 symbolOop clinit_name = vmSymbols::class_initializer_name(); |
790 Symbol* clinit_name = vmSymbols::class_initializer_name(); |
787 if (name == clinit_name) clinit_name = NULL; // hack for exposing <clinit> |
791 if (name == clinit_name) clinit_name = NULL; // hack for exposing <clinit> |
788 bool negate_name_test = false; |
792 bool negate_name_test = false; |
789 // fix name so that it captures the intention of IS_CONSTRUCTOR |
793 // fix name so that it captures the intention of IS_CONSTRUCTOR |
790 if (!(match_flags & IS_METHOD)) { |
794 if (!(match_flags & IS_METHOD)) { |
791 // constructors only |
795 // constructors only |
805 } else { |
809 } else { |
806 // caller will accept either sort; no need to adjust name |
810 // caller will accept either sort; no need to adjust name |
807 } |
811 } |
808 for (MethodStream st(k, local_only, !search_intfc); !st.eos(); st.next()) { |
812 for (MethodStream st(k, local_only, !search_intfc); !st.eos(); st.next()) { |
809 methodOop m = st.method(); |
813 methodOop m = st.method(); |
810 symbolOop m_name = m->name(); |
814 Symbol* m_name = m->name(); |
811 if (m_name == clinit_name) |
815 if (m_name == clinit_name) |
812 continue; |
816 continue; |
813 if (name != NULL && ((m_name != name) ^ negate_name_test)) |
817 if (name != NULL && ((m_name != name) ^ negate_name_test)) |
814 continue; |
818 continue; |
815 if (sig != NULL && m->signature() != sig) |
819 if (sig != NULL && m->signature() != sig) |
926 if (!Klass::cast(klass)->oop_is_instance()) return false; |
930 if (!Klass::cast(klass)->oop_is_instance()) return false; |
927 instanceKlass* ik = instanceKlass::cast(klass); |
931 instanceKlass* ik = instanceKlass::cast(klass); |
928 // Must be on the boot class path: |
932 // Must be on the boot class path: |
929 if (ik->class_loader() != NULL) return false; |
933 if (ik->class_loader() != NULL) return false; |
930 // Check the name. |
934 // Check the name. |
931 symbolOop name = ik->name(); |
935 Symbol* name = ik->name(); |
932 for (int i = 0; ; i++) { |
936 for (int i = 0; ; i++) { |
933 const char* test_name = always_null_names[i]; |
937 const char* test_name = always_null_names[i]; |
934 if (test_name == NULL) break; |
938 if (test_name == NULL) break; |
935 if (name->equals(test_name)) |
939 if (name->equals(test_name)) |
936 return true; |
940 return true; |
1024 objArrayHandle ptypes(THREAD, java_dyn_MethodType::ptypes(mtype())); |
1028 objArrayHandle ptypes(THREAD, java_dyn_MethodType::ptypes(mtype())); |
1025 int pnum = first_ptype_pos; |
1029 int pnum = first_ptype_pos; |
1026 int pmax = ptypes->length(); |
1030 int pmax = ptypes->length(); |
1027 int mnum = 0; // method argument |
1031 int mnum = 0; // method argument |
1028 const char* err = NULL; |
1032 const char* err = NULL; |
|
1033 ResourceMark rm(THREAD); |
1029 for (SignatureStream ss(m->signature()); !ss.is_done(); ss.next()) { |
1034 for (SignatureStream ss(m->signature()); !ss.is_done(); ss.next()) { |
1030 oop ptype_oop = NULL; |
1035 oop ptype_oop = NULL; |
1031 if (ss.at_return_type()) { |
1036 if (ss.at_return_type()) { |
1032 if (pnum != pmax) |
1037 if (pnum != pmax) |
1033 { err = "too many arguments"; break; } |
1038 { err = "too many arguments"; break; } |
1059 // null matches any reference |
1064 // null matches any reference |
1060 continue; |
1065 continue; |
1061 } |
1066 } |
1062 KlassHandle pklass_handle(THREAD, pklass); pklass = NULL; |
1067 KlassHandle pklass_handle(THREAD, pklass); pklass = NULL; |
1063 // If we fail to resolve types at this point, we will throw an error. |
1068 // If we fail to resolve types at this point, we will throw an error. |
1064 symbolOop name_oop = ss.as_symbol(CHECK); |
1069 Symbol* name = ss.as_symbol(CHECK); |
1065 symbolHandle name(THREAD, name_oop); |
|
1066 instanceKlass* mk = instanceKlass::cast(m->method_holder()); |
1070 instanceKlass* mk = instanceKlass::cast(m->method_holder()); |
1067 Handle loader(THREAD, mk->class_loader()); |
1071 Handle loader(THREAD, mk->class_loader()); |
1068 Handle domain(THREAD, mk->protection_domain()); |
1072 Handle domain(THREAD, mk->protection_domain()); |
1069 mklass = SystemDictionary::resolve_or_null(name, loader, domain, CHECK); |
1073 mklass = SystemDictionary::resolve_or_null(name, loader, domain, CHECK); |
1070 pklass = pklass_handle(); |
1074 pklass = pklass_handle(); |
1071 if (mklass == NULL && pklass != NULL && |
1075 if (mklass == NULL && pklass != NULL && |
1072 Klass::cast(pklass)->name() == name() && |
1076 Klass::cast(pklass)->name() == name && |
1073 m->is_method_handle_invoke()) { |
1077 m->is_method_handle_invoke()) { |
1074 // Assume a match. We can't really decode the signature of MH.invoke*. |
1078 // Assume a match. We can't really decode the signature of MH.invoke*. |
1075 continue; |
1079 continue; |
1076 } |
1080 } |
1077 } |
1081 } |
2286 if (erased_jh == NULL) return; |
2290 if (erased_jh == NULL) return; |
2287 if (TraceMethodHandles) { |
2291 if (TraceMethodHandles) { |
2288 tty->print("creating MethodType form "); |
2292 tty->print("creating MethodType form "); |
2289 if (WizardMode || Verbose) { // Warning: this calls Java code on the MH! |
2293 if (WizardMode || Verbose) { // Warning: this calls Java code on the MH! |
2290 // call Object.toString() |
2294 // call Object.toString() |
2291 symbolOop name = vmSymbols::toString_name(), sig = vmSymbols::void_string_signature(); |
2295 Symbol* name = vmSymbols::toString_name(); |
|
2296 Symbol* sig = vmSymbols::void_string_signature(); |
2292 JavaCallArguments args(Handle(THREAD, JNIHandles::resolve_non_null(erased_jh))); |
2297 JavaCallArguments args(Handle(THREAD, JNIHandles::resolve_non_null(erased_jh))); |
2293 JavaValue result(T_OBJECT); |
2298 JavaValue result(T_OBJECT); |
2294 JavaCalls::call_virtual(&result, SystemDictionary::Object_klass(), name, sig, |
2299 JavaCalls::call_virtual(&result, SystemDictionary::Object_klass(), name, sig, |
2295 &args, CHECK); |
2300 &args, CHECK); |
2296 Handle str(THREAD, (oop)result.get_jobject()); |
2301 Handle str(THREAD, (oop)result.get_jobject()); |
2450 klassOop k_oop = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz_jh)); |
2455 klassOop k_oop = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz_jh)); |
2451 |
2456 |
2452 objArrayOop results = (objArrayOop) JNIHandles::resolve(results_jh); |
2457 objArrayOop results = (objArrayOop) JNIHandles::resolve(results_jh); |
2453 if (results == NULL || !results->is_objArray()) return -1; |
2458 if (results == NULL || !results->is_objArray()) return -1; |
2454 |
2459 |
2455 symbolOop name = NULL, sig = NULL; |
2460 TempNewSymbol name = NULL; |
|
2461 TempNewSymbol sig = NULL; |
2456 if (name_jh != NULL) { |
2462 if (name_jh != NULL) { |
2457 name = java_lang_String::as_symbol_or_null(JNIHandles::resolve_non_null(name_jh)); |
2463 name = java_lang_String::as_symbol_or_null(JNIHandles::resolve_non_null(name_jh)); |
2458 if (name == NULL) return 0; // a match is not possible |
2464 if (name == NULL) return 0; // a match is not possible |
2459 } |
2465 } |
2460 if (sig_jh != NULL) { |
2466 if (sig_jh != NULL) { |
2609 } |
2615 } |
2610 |
2616 |
2611 if (enable_MH) { |
2617 if (enable_MH) { |
2612 KlassHandle MHI_klass = SystemDictionaryHandles::MethodHandleImpl_klass(); |
2618 KlassHandle MHI_klass = SystemDictionaryHandles::MethodHandleImpl_klass(); |
2613 if (MHI_klass.not_null()) { |
2619 if (MHI_klass.not_null()) { |
2614 symbolHandle raiseException_name = oopFactory::new_symbol_handle("raiseException", CHECK); |
2620 TempNewSymbol raiseException_name = SymbolTable::new_symbol("raiseException", CHECK); |
2615 symbolHandle raiseException_sig = oopFactory::new_symbol_handle("(ILjava/lang/Object;Ljava/lang/Object;)V", CHECK); |
2621 TempNewSymbol raiseException_sig = SymbolTable::new_symbol("(ILjava/lang/Object;Ljava/lang/Object;)V", CHECK); |
2616 methodOop raiseException_method = instanceKlass::cast(MHI_klass->as_klassOop()) |
2622 methodOop raiseException_method = instanceKlass::cast(MHI_klass->as_klassOop()) |
2617 ->find_method(raiseException_name(), raiseException_sig()); |
2623 ->find_method(raiseException_name, raiseException_sig); |
2618 if (raiseException_method != NULL && raiseException_method->is_static()) { |
2624 if (raiseException_method != NULL && raiseException_method->is_static()) { |
2619 MethodHandles::set_raise_exception_method(raiseException_method); |
2625 MethodHandles::set_raise_exception_method(raiseException_method); |
2620 } else { |
2626 } else { |
2621 warning("JSR 292 method handle code is mismatched to this JVM. Disabling support."); |
2627 warning("JSR 292 method handle code is mismatched to this JVM. Disabling support."); |
2622 enable_MH = false; |
2628 enable_MH = false; |