comparison src/share/vm/interpreter/linkResolver.cpp @ 13436:9fbabcbb875b

8028741: Interface Method Resolution should skip static and non-public methods in j.l.Object Summary: Implementation of JDK 8 JVMS 5.4.3.4 specification change to skip static and non-public methods of java.lang.Object for interface method resolution. Reviewed-by: acorn, coleenp Contributed-by: lois.foltan@oracle.com
author hseigel
date Tue, 10 Dec 2013 16:18:26 -0500
parents 769557390c43
children 02f27ecb4f3a 2353011244bd
comparison
equal deleted inserted replaced
13435:bf15208b72a5 13436:9fbabcbb875b
240 // 240 //
241 // According to JVM spec. $5.4.3c & $5.4.3d 241 // According to JVM spec. $5.4.3c & $5.4.3d
242 242
243 // Look up method in klasses, including static methods 243 // Look up method in klasses, including static methods
244 // Then look up local default 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) { 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); 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
247 if (result_oop == NULL) { 259 if (result_oop == NULL) {
248 Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods(); 260 Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods();
249 if (default_methods != NULL) { 261 if (default_methods != NULL) {
250 result_oop = InstanceKlass::find_method(default_methods, name, signature); 262 result_oop = InstanceKlass::find_method(default_methods, name, signature);
251 } 263 }
418 methodHandle sel_method, 430 methodHandle sel_method,
419 TRAPS) { 431 TRAPS) {
420 432
421 AccessFlags flags = sel_method->access_flags(); 433 AccessFlags flags = sel_method->access_flags();
422 434
423 // Special case #1: arrays always override "clone". JVMS 2.15. 435 // Special case: arrays always override "clone". JVMS 2.15.
424 // If the resolved klass is an array class, and the declaring class 436 // 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 437 // is java.lang.Object and the method is "clone", set the flags
426 // to public. 438 // 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 // 439 //
436 // We'll check for each method name first and then java.lang.Object 440 // We'll check for the method name first, as that's most likely
437 // to best short-circuit out of these tests. 441 // to be false (so we'll short-circuit out of these tests).
438 if (((sel_method->name() == vmSymbols::clone_name() && 442 if (sel_method->name() == vmSymbols::clone_name() &&
439 (resolved_klass->oop_is_array() || resolved_klass->is_interface())) || 443 sel_klass() == SystemDictionary::Object_klass() &&
440 (sel_method->name() == vmSymbols::finalize_method_name() && 444 resolved_klass->oop_is_array()) {
441 resolved_klass->is_interface())) &&
442 sel_klass() == SystemDictionary::Object_klass()) {
443 // We need to change "protected" to "public". 445 // We need to change "protected" to "public".
444 assert(flags.is_protected(), "clone or finalize not protected?"); 446 assert(flags.is_protected(), "clone not protected?");
445 jint new_flags = flags.as_int(); 447 jint new_flags = flags.as_int();
446 new_flags = new_flags & (~JVM_ACC_PROTECTED); 448 new_flags = new_flags & (~JVM_ACC_PROTECTED);
447 new_flags = new_flags | JVM_ACC_PUBLIC; 449 new_flags = new_flags | JVM_ACC_PUBLIC;
448 flags.set_flags(new_flags); 450 flags.set_flags(new_flags);
449 } 451 }
529 resolved_klass()->external_name()); 531 resolved_klass()->external_name());
530 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); 532 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
531 } 533 }
532 534
533 // 2. lookup method in resolved klass and its super klasses 535 // 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); 536 lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, true, false, CHECK);
535 537
536 if (resolved_method.is_null()) { // not found in the class hierarchy 538 if (resolved_method.is_null()) { // not found in the class hierarchy
537 // 3. lookup method in all the interfaces implemented by the resolved klass 539 // 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); 540 lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
539 541
626 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); 628 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
627 } 629 }
628 630
629 // lookup method in this interface or its super, java.lang.Object 631 // lookup method in this interface or its super, java.lang.Object
630 // JDK8: also look for static methods 632 // JDK8: also look for static methods
631 lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, false, CHECK); 633 lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, false, true, CHECK);
632 634
633 if (resolved_method.is_null()) { 635 if (resolved_method.is_null()) {
634 // lookup method in all the super-interfaces 636 // lookup method in all the super-interfaces
635 lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK); 637 lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
636 if (resolved_method.is_null()) { 638 if (resolved_method.is_null()) {