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;