Mercurial > hg > graal-compiler
comparison src/share/vm/interpreter/linkResolver.cpp @ 18058:54bc75c144b0
Merge
author | asaha |
---|---|
date | Thu, 29 May 2014 13:14:25 -0700 |
parents | 096a7e12d63f 78bbf4d43a14 |
children | eaf39a954227 9906d432d6db |
comparison
equal
deleted
inserted
replaced
18055:1fa005fb28f5 | 18058:54bc75c144b0 |
---|---|
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, bool in_imethod_resolve, 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 // Ignore overpasses so statics can be found during resolution |
247 Method* result_oop = klass->uncached_lookup_method(name, signature, Klass::skip_overpass); | |
247 | 248 |
248 if (klass->oop_is_array()) { | 249 if (klass->oop_is_array()) { |
249 // Only consider klass and super klass for arrays | 250 // Only consider klass and super klass for arrays |
250 result = methodHandle(THREAD, result_oop); | 251 result = methodHandle(THREAD, result_oop); |
251 return; | 252 return; |
260 (result_oop->is_static() || !result_oop->is_public()) && | 261 (result_oop->is_static() || !result_oop->is_public()) && |
261 result_oop->method_holder() == SystemDictionary::Object_klass()) { | 262 result_oop->method_holder() == SystemDictionary::Object_klass()) { |
262 result_oop = NULL; | 263 result_oop = NULL; |
263 } | 264 } |
264 | 265 |
266 // Before considering default methods, check for an overpass in the | |
267 // current class if a method has not been found. | |
268 if (result_oop == NULL) { | |
269 result_oop = InstanceKlass::cast(klass())->find_method(name, signature); | |
270 } | |
271 | |
265 if (result_oop == NULL) { | 272 if (result_oop == NULL) { |
266 Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods(); | 273 Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods(); |
267 if (default_methods != NULL) { | 274 if (default_methods != NULL) { |
268 result_oop = InstanceKlass::find_method(default_methods, name, signature); | 275 result_oop = InstanceKlass::find_method(default_methods, name, signature); |
269 } | 276 } |
280 } | 287 } |
281 | 288 |
282 // returns first instance method | 289 // returns first instance method |
283 // Looks up method in classes, then looks up local default methods | 290 // Looks up method in classes, then looks up local default methods |
284 void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { | 291 void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { |
285 Method* result_oop = klass->uncached_lookup_method(name, signature); | 292 Method* result_oop = klass->uncached_lookup_method(name, signature, Klass::normal); |
286 result = methodHandle(THREAD, result_oop); | 293 result = methodHandle(THREAD, result_oop); |
287 while (!result.is_null() && result->is_static() && result->method_holder()->super() != NULL) { | 294 while (!result.is_null() && result->is_static() && result->method_holder()->super() != NULL) { |
288 KlassHandle super_klass = KlassHandle(THREAD, result->method_holder()->super()); | 295 KlassHandle super_klass = KlassHandle(THREAD, result->method_holder()->super()); |
289 result = methodHandle(THREAD, super_klass->uncached_lookup_method(name, signature)); | 296 result = methodHandle(THREAD, super_klass->uncached_lookup_method(name, signature, Klass::normal)); |
290 } | 297 } |
291 | 298 |
292 if (klass->oop_is_array()) { | 299 if (klass->oop_is_array()) { |
293 // Only consider klass and super klass for arrays | 300 // Only consider klass and super klass for arrays |
294 return; | 301 return; |
311 Symbol* signature = resolved_method->signature(); | 318 Symbol* signature = resolved_method->signature(); |
312 | 319 |
313 // First check in default method array | 320 // First check in default method array |
314 if (!resolved_method->is_abstract() && | 321 if (!resolved_method->is_abstract() && |
315 (InstanceKlass::cast(klass())->default_methods() != NULL)) { | 322 (InstanceKlass::cast(klass())->default_methods() != NULL)) { |
316 int index = InstanceKlass::find_method_index(InstanceKlass::cast(klass())->default_methods(), name, signature); | 323 int index = InstanceKlass::find_method_index(InstanceKlass::cast(klass())->default_methods(), name, signature, false); |
317 if (index >= 0 ) { | 324 if (index >= 0 ) { |
318 vtable_index = InstanceKlass::cast(klass())->default_vtable_indices()->at(index); | 325 vtable_index = InstanceKlass::cast(klass())->default_vtable_indices()->at(index); |
319 } | 326 } |
320 } | 327 } |
321 if (vtable_index == Method::invalid_vtable_index) { | 328 if (vtable_index == Method::invalid_vtable_index) { |
331 InstanceKlass *ik = InstanceKlass::cast(klass()); | 338 InstanceKlass *ik = InstanceKlass::cast(klass()); |
332 | 339 |
333 // Specify 'true' in order to skip default methods when searching the | 340 // Specify 'true' in order to skip default methods when searching the |
334 // interfaces. Function lookup_method_in_klasses() already looked for | 341 // interfaces. Function lookup_method_in_klasses() already looked for |
335 // the method in the default methods table. | 342 // the method in the default methods table. |
336 result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name, signature, true)); | 343 result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name, signature, Klass::skip_defaults)); |
337 } | 344 } |
338 | 345 |
339 void LinkResolver::lookup_polymorphic_method(methodHandle& result, | 346 void LinkResolver::lookup_polymorphic_method(methodHandle& result, |
340 KlassHandle klass, Symbol* name, Symbol* full_signature, | 347 KlassHandle klass, Symbol* name, Symbol* full_signature, |
341 KlassHandle current_klass, | 348 KlassHandle current_klass, |
573 method_name, | 580 method_name, |
574 method_signature), | 581 method_signature), |
575 nested_exception); | 582 nested_exception); |
576 } | 583 } |
577 | 584 |
578 // 5. check if method is concrete | 585 // 5. access checks, access checking may be turned off when calling from within the VM. |
579 if (resolved_method->is_abstract() && !resolved_klass->is_abstract()) { | |
580 ResourceMark rm(THREAD); | |
581 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), | |
582 Method::name_and_sig_as_C_string(resolved_klass(), | |
583 method_name, | |
584 method_signature)); | |
585 } | |
586 | |
587 // 6. access checks, access checking may be turned off when calling from within the VM. | |
588 if (check_access) { | 586 if (check_access) { |
589 assert(current_klass.not_null() , "current_klass should not be null"); | 587 assert(current_klass.not_null() , "current_klass should not be null"); |
590 | 588 |
591 // check if method can be accessed by the referring class | 589 // check if method can be accessed by the referring class |
592 check_method_accessability(current_klass, | 590 check_method_accessability(current_klass, |
658 THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(), | 656 THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(), |
659 Method::name_and_sig_as_C_string(resolved_klass(), | 657 Method::name_and_sig_as_C_string(resolved_klass(), |
660 method_name, | 658 method_name, |
661 method_signature)); | 659 method_signature)); |
662 } | 660 } |
663 | |
664 if (nostatics && resolved_method->is_static()) { | |
665 ResourceMark rm(THREAD); | |
666 char buf[200]; | |
667 jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s", Method::name_and_sig_as_C_string(resolved_klass(), | |
668 resolved_method->name(), | |
669 resolved_method->signature())); | |
670 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); | |
671 } | |
672 | |
673 | 661 |
674 if (check_access) { | 662 if (check_access) { |
675 // JDK8 adds non-public interface methods, and accessability check requirement | 663 // JDK8 adds non-public interface methods, and accessability check requirement |
676 assert(current_klass.not_null() , "current_klass should not be null"); | 664 assert(current_klass.not_null() , "current_klass should not be null"); |
677 | 665 |
712 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); | 700 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); |
713 } | 701 } |
714 } | 702 } |
715 } | 703 } |
716 | 704 |
705 if (nostatics && resolved_method->is_static()) { | |
706 ResourceMark rm(THREAD); | |
707 char buf[200]; | |
708 jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s", | |
709 Method::name_and_sig_as_C_string(resolved_klass(), | |
710 resolved_method->name(), resolved_method->signature())); | |
711 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); | |
712 } | |
713 | |
717 if (TraceItables && Verbose) { | 714 if (TraceItables && Verbose) { |
718 ResourceMark rm(THREAD); | 715 ResourceMark rm(THREAD); |
719 tty->print("invokeinterface resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ", | 716 tty->print("invokeinterface resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ", |
720 (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()), | 717 (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()), |
721 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()), | 718 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()), |
1643 &resolved_appendix, | 1640 &resolved_appendix, |
1644 &resolved_method_type, | 1641 &resolved_method_type, |
1645 THREAD); | 1642 THREAD); |
1646 if (HAS_PENDING_EXCEPTION) { | 1643 if (HAS_PENDING_EXCEPTION) { |
1647 if (TraceMethodHandles) { | 1644 if (TraceMethodHandles) { |
1648 tty->print_cr("invokedynamic throws BSME for "INTPTR_FORMAT, (void *)PENDING_EXCEPTION); | 1645 tty->print_cr("invokedynamic throws BSME for " INTPTR_FORMAT, p2i((void *)PENDING_EXCEPTION)); |
1649 PENDING_EXCEPTION->print(); | 1646 PENDING_EXCEPTION->print(); |
1650 } | 1647 } |
1651 if (PENDING_EXCEPTION->is_a(SystemDictionary::BootstrapMethodError_klass())) { | 1648 if (PENDING_EXCEPTION->is_a(SystemDictionary::BootstrapMethodError_klass())) { |
1652 // throw these guys, since they are already wrapped | 1649 // throw these guys, since they are already wrapped |
1653 return; | 1650 return; |