Mercurial > hg > graal-compiler
comparison src/share/vm/prims/methodHandles.cpp @ 2177:3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
Summary: move symbols from permgen into C heap and reference count them
Reviewed-by: never, acorn, jmasa, stefank
author | coleenp |
---|---|
date | Thu, 27 Jan 2011 16:11:27 -0800 |
parents | d810e9a3fc33 |
children | 72dee110246f |
comparison
equal
deleted
inserted
replaced
2176:27e4ea99855d | 2177:3582bf76420e |
---|---|
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; |