src/share/vm/interpreter/linkResolver.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File bug_jdk8028741 Sdiff src/share/vm/interpreter

src/share/vm/interpreter/linkResolver.cpp

Print this page




 225       "tried to access class %s from class %s",
 226       sel_klass->external_name(),
 227       ref_klass->external_name()
 228     );
 229     return;
 230   }
 231 }
 232 
 233 void LinkResolver::resolve_klass(KlassHandle& result, constantPoolHandle pool, int index, TRAPS) {
 234   Klass* result_oop = pool->klass_ref_at(index, CHECK);
 235   result = KlassHandle(THREAD, result_oop);
 236 }
 237 
 238 //------------------------------------------------------------------------------------------------------------------------
 239 // Method resolution
 240 //
 241 // According to JVM spec. $5.4.3c & $5.4.3d
 242 
 243 // Look up method in klasses, including static methods
 244 // Then look up local default methods
 245 void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, TRAPS) {
 246   Method* result_oop = klass->uncached_lookup_method(name, signature);












 247   if (result_oop == NULL) {
 248     Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods();
 249     if (default_methods != NULL) {
 250       result_oop = InstanceKlass::find_method(default_methods, name, signature);
 251     }
 252   }
 253 
 254   if (checkpolymorphism && EnableInvokeDynamic && result_oop != NULL) {
 255     vmIntrinsics::ID iid = result_oop->intrinsic_id();
 256     if (MethodHandles::is_signature_polymorphic(iid)) {
 257       // Do not link directly to these.  The VM must produce a synthetic one using lookup_polymorphic_method.
 258       return;
 259     }
 260   }
 261   result = methodHandle(THREAD, result_oop);
 262 }
 263 
 264 // returns first instance method
 265 // Looks up method in classes, then looks up local default methods
 266 void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {


 403                err_msg("%d != %d", actual_size_of_params, expected_size_of_params));
 404 #endif //ASSERT
 405 
 406         assert(appendix_result_or_null != NULL, "");
 407         (*appendix_result_or_null) = appendix;
 408         (*method_type_result)      = method_type;
 409         return;
 410       }
 411     }
 412   }
 413 }
 414 
 415 void LinkResolver::check_method_accessability(KlassHandle ref_klass,
 416                                               KlassHandle resolved_klass,
 417                                               KlassHandle sel_klass,
 418                                               methodHandle sel_method,
 419                                               TRAPS) {
 420 
 421   AccessFlags flags = sel_method->access_flags();
 422 
 423   // Special case #1:  arrays always override "clone". JVMS 2.15.
 424   // If the resolved klass is an array class, and the declaring class
 425   // is java.lang.Object and the method is "clone", set the flags
 426   // to public.
 427   // Special case #2:  If the resolved klass is an interface, and
 428   // the declaring class is java.lang.Object, and the method is
 429   // "clone" or "finalize", set the flags to public. If the
 430   // resolved interface does not contain "clone" or "finalize"
 431   // methods, the method/interface method resolution looks to
 432   // the interface's super class, java.lang.Object.  With JDK 8
 433   // interface accessability check requirement, special casing
 434   // this scenario is necessary to avoid an IAE.
 435   //
 436   // We'll check for each method name first and then java.lang.Object
 437   // to best short-circuit out of these tests.
 438   if (((sel_method->name() == vmSymbols::clone_name() &&
 439         (resolved_klass->oop_is_array() || resolved_klass->is_interface())) ||
 440        (sel_method->name() == vmSymbols::finalize_method_name() &&
 441         resolved_klass->is_interface())) &&
 442       sel_klass() == SystemDictionary::Object_klass()) {
 443     // We need to change "protected" to "public".
 444     assert(flags.is_protected(), "clone or finalize not protected?");
 445     jint new_flags = flags.as_int();
 446     new_flags = new_flags & (~JVM_ACC_PROTECTED);
 447     new_flags = new_flags | JVM_ACC_PUBLIC;
 448     flags.set_flags(new_flags);
 449   }
 450 //  assert(extra_arg_result_or_null != NULL, "must be able to return extra argument");
 451 
 452   if (!Reflection::verify_field_access(ref_klass(),
 453                                        resolved_klass(),
 454                                        sel_klass(),
 455                                        flags,
 456                                        true)) {
 457     ResourceMark rm(THREAD);
 458     Exceptions::fthrow(
 459       THREAD_AND_LOCATION,
 460       vmSymbols::java_lang_IllegalAccessError(),
 461       "tried to access method %s.%s%s from class %s",
 462       sel_klass->external_name(),
 463       sel_method->name()->as_C_string(),
 464       sel_method->signature()->as_C_string(),


 514   }
 515 }
 516 
 517 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass,
 518                                   Symbol* method_name, Symbol* method_signature,
 519                                   KlassHandle current_klass, bool check_access,
 520                                   bool require_methodref, TRAPS) {
 521 
 522   Handle nested_exception;
 523 
 524   // 1. check if methodref required, that resolved_klass is not interfacemethodref
 525   if (require_methodref && resolved_klass->is_interface()) {
 526     ResourceMark rm(THREAD);
 527     char buf[200];
 528     jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected",
 529         resolved_klass()->external_name());
 530     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
 531   }
 532 
 533   // 2. lookup method in resolved klass and its super klasses
 534   lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, true, CHECK);
 535 
 536   if (resolved_method.is_null()) { // not found in the class hierarchy
 537     // 3. lookup method in all the interfaces implemented by the resolved klass
 538     lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
 539 
 540     if (resolved_method.is_null()) {
 541       // JSR 292:  see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc
 542       lookup_polymorphic_method(resolved_method, resolved_klass, method_name, method_signature,
 543                                 current_klass, (Handle*)NULL, (Handle*)NULL, THREAD);
 544       if (HAS_PENDING_EXCEPTION) {
 545         nested_exception = Handle(THREAD, PENDING_EXCEPTION);
 546         CLEAR_PENDING_EXCEPTION;
 547       }
 548     }
 549 
 550     if (resolved_method.is_null()) {
 551       // 4. method lookup failed
 552       ResourceMark rm(THREAD);
 553       THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(),
 554                       Method::name_and_sig_as_C_string(resolved_klass(),


 611 }
 612 
 613 void LinkResolver::resolve_interface_method(methodHandle& resolved_method,
 614                                             KlassHandle resolved_klass,
 615                                             Symbol* method_name,
 616                                             Symbol* method_signature,
 617                                             KlassHandle current_klass,
 618                                             bool check_access,
 619                                             bool nostatics, TRAPS) {
 620 
 621  // check if klass is interface
 622   if (!resolved_klass->is_interface()) {
 623     ResourceMark rm(THREAD);
 624     char buf[200];
 625     jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name());
 626     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
 627   }
 628 
 629   // lookup method in this interface or its super, java.lang.Object
 630   // JDK8: also look for static methods
 631   lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, false, CHECK);
 632 
 633   if (resolved_method.is_null()) {
 634     // lookup method in all the super-interfaces
 635     lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
 636     if (resolved_method.is_null()) {
 637       // no method found
 638       ResourceMark rm(THREAD);
 639       THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(),
 640                 Method::name_and_sig_as_C_string(resolved_klass(),
 641                                                         method_name,
 642                                                         method_signature));
 643     }
 644   }
 645 
 646   if (nostatics && resolved_method->is_static()) {
 647     ResourceMark rm(THREAD);
 648     char buf[200];
 649     jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s", Method::name_and_sig_as_C_string(resolved_klass(),
 650                                                       resolved_method->name(),
 651                                                       resolved_method->signature()));




 225       "tried to access class %s from class %s",
 226       sel_klass->external_name(),
 227       ref_klass->external_name()
 228     );
 229     return;
 230   }
 231 }
 232 
 233 void LinkResolver::resolve_klass(KlassHandle& result, constantPoolHandle pool, int index, TRAPS) {
 234   Klass* result_oop = pool->klass_ref_at(index, CHECK);
 235   result = KlassHandle(THREAD, result_oop);
 236 }
 237 
 238 //------------------------------------------------------------------------------------------------------------------------
 239 // Method resolution
 240 //
 241 // According to JVM spec. $5.4.3c & $5.4.3d
 242 
 243 // Look up method in klasses, including static methods
 244 // Then look up local default methods
 245 void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, bool in_imethod_resolve, TRAPS) {
 246   Method* result_oop = klass->uncached_lookup_method(name, signature);
 247 
 248   // JDK 8, JVMS 5.4.3.4: Interface method resolution should
 249   // ignore static and non-public methods of java.lang.Object,
 250   // like clone, finalize, registerNatives.
 251   if (in_imethod_resolve &&
 252       result_oop != NULL &&
 253       klass->is_interface() &&
 254       (result_oop->is_static() || !result_oop->is_public()) &&
 255       result_oop->method_holder() == SystemDictionary::Object_klass()) {
 256     result_oop = NULL;
 257   }
 258 
 259   if (result_oop == NULL) {
 260     Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods();
 261     if (default_methods != NULL) {
 262       result_oop = InstanceKlass::find_method(default_methods, name, signature);
 263     }
 264   }
 265 
 266   if (checkpolymorphism && EnableInvokeDynamic && result_oop != NULL) {
 267     vmIntrinsics::ID iid = result_oop->intrinsic_id();
 268     if (MethodHandles::is_signature_polymorphic(iid)) {
 269       // Do not link directly to these.  The VM must produce a synthetic one using lookup_polymorphic_method.
 270       return;
 271     }
 272   }
 273   result = methodHandle(THREAD, result_oop);
 274 }
 275 
 276 // returns first instance method
 277 // Looks up method in classes, then looks up local default methods
 278 void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {


 415                err_msg("%d != %d", actual_size_of_params, expected_size_of_params));
 416 #endif //ASSERT
 417 
 418         assert(appendix_result_or_null != NULL, "");
 419         (*appendix_result_or_null) = appendix;
 420         (*method_type_result)      = method_type;
 421         return;
 422       }
 423     }
 424   }
 425 }
 426 
 427 void LinkResolver::check_method_accessability(KlassHandle ref_klass,
 428                                               KlassHandle resolved_klass,
 429                                               KlassHandle sel_klass,
 430                                               methodHandle sel_method,
 431                                               TRAPS) {
 432 
 433   AccessFlags flags = sel_method->access_flags();
 434 
 435   // Special case:  arrays always override "clone". JVMS 2.15.
 436   // If the resolved klass is an array class, and the declaring class
 437   // is java.lang.Object and the method is "clone", set the flags
 438   // to public.








 439   //
 440   // We'll check for the method name first, as that's most likely
 441   // to be false (so we'll short-circuit out of these tests).
 442   if (sel_method->name() == vmSymbols::clone_name() &&
 443       sel_klass() == SystemDictionary::Object_klass() &&
 444       resolved_klass->oop_is_array()) {


 445     // We need to change "protected" to "public".
 446     assert(flags.is_protected(), "clone not protected?");
 447     jint new_flags = flags.as_int();
 448     new_flags = new_flags & (~JVM_ACC_PROTECTED);
 449     new_flags = new_flags | JVM_ACC_PUBLIC;
 450     flags.set_flags(new_flags);
 451   }
 452 //  assert(extra_arg_result_or_null != NULL, "must be able to return extra argument");
 453 
 454   if (!Reflection::verify_field_access(ref_klass(),
 455                                        resolved_klass(),
 456                                        sel_klass(),
 457                                        flags,
 458                                        true)) {
 459     ResourceMark rm(THREAD);
 460     Exceptions::fthrow(
 461       THREAD_AND_LOCATION,
 462       vmSymbols::java_lang_IllegalAccessError(),
 463       "tried to access method %s.%s%s from class %s",
 464       sel_klass->external_name(),
 465       sel_method->name()->as_C_string(),
 466       sel_method->signature()->as_C_string(),


 516   }
 517 }
 518 
 519 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass,
 520                                   Symbol* method_name, Symbol* method_signature,
 521                                   KlassHandle current_klass, bool check_access,
 522                                   bool require_methodref, TRAPS) {
 523 
 524   Handle nested_exception;
 525 
 526   // 1. check if methodref required, that resolved_klass is not interfacemethodref
 527   if (require_methodref && resolved_klass->is_interface()) {
 528     ResourceMark rm(THREAD);
 529     char buf[200];
 530     jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected",
 531         resolved_klass()->external_name());
 532     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
 533   }
 534 
 535   // 2. lookup method in resolved klass and its super klasses
 536   lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, true, false, CHECK);
 537 
 538   if (resolved_method.is_null()) { // not found in the class hierarchy
 539     // 3. lookup method in all the interfaces implemented by the resolved klass
 540     lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
 541 
 542     if (resolved_method.is_null()) {
 543       // JSR 292:  see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc
 544       lookup_polymorphic_method(resolved_method, resolved_klass, method_name, method_signature,
 545                                 current_klass, (Handle*)NULL, (Handle*)NULL, THREAD);
 546       if (HAS_PENDING_EXCEPTION) {
 547         nested_exception = Handle(THREAD, PENDING_EXCEPTION);
 548         CLEAR_PENDING_EXCEPTION;
 549       }
 550     }
 551 
 552     if (resolved_method.is_null()) {
 553       // 4. method lookup failed
 554       ResourceMark rm(THREAD);
 555       THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(),
 556                       Method::name_and_sig_as_C_string(resolved_klass(),


 613 }
 614 
 615 void LinkResolver::resolve_interface_method(methodHandle& resolved_method,
 616                                             KlassHandle resolved_klass,
 617                                             Symbol* method_name,
 618                                             Symbol* method_signature,
 619                                             KlassHandle current_klass,
 620                                             bool check_access,
 621                                             bool nostatics, TRAPS) {
 622 
 623  // check if klass is interface
 624   if (!resolved_klass->is_interface()) {
 625     ResourceMark rm(THREAD);
 626     char buf[200];
 627     jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name());
 628     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
 629   }
 630 
 631   // lookup method in this interface or its super, java.lang.Object
 632   // JDK8: also look for static methods
 633   lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, false, true, CHECK);
 634 
 635   if (resolved_method.is_null()) {
 636     // lookup method in all the super-interfaces
 637     lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
 638     if (resolved_method.is_null()) {
 639       // no method found
 640       ResourceMark rm(THREAD);
 641       THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(),
 642                 Method::name_and_sig_as_C_string(resolved_klass(),
 643                                                         method_name,
 644                                                         method_signature));
 645     }
 646   }
 647 
 648   if (nostatics && resolved_method->is_static()) {
 649     ResourceMark rm(THREAD);
 650     char buf[200];
 651     jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s", Method::name_and_sig_as_C_string(resolved_klass(),
 652                                                       resolved_method->name(),
 653                                                       resolved_method->signature()));


src/share/vm/interpreter/linkResolver.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File