Mercurial > hg > truffle
comparison src/share/vm/interpreter/linkResolver.cpp @ 18041:52b4284cb496
Merge with jdk8u20-b26
author | Gilles Duboscq <duboscq@ssw.jku.at> |
---|---|
date | Wed, 15 Oct 2014 16:02:50 +0200 |
parents | 89152779163c 78bbf4d43a14 |
children | eaf39a954227 |
comparison
equal
deleted
inserted
replaced
17606:45d7b2c7029d | 18041:52b4284cb496 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
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 // JDK 8, JVMS 5.4.3.4: Interface method resolution should | 249 // JDK 8, JVMS 5.4.3.4: Interface method resolution should |
249 // ignore static and non-public methods of java.lang.Object, | 250 // ignore static and non-public methods of java.lang.Object, |
250 // like clone, finalize, registerNatives. | 251 // like clone, finalize, registerNatives. |
251 if (in_imethod_resolve && | 252 if (in_imethod_resolve && |
254 (result_oop->is_static() || !result_oop->is_public()) && | 255 (result_oop->is_static() || !result_oop->is_public()) && |
255 result_oop->method_holder() == SystemDictionary::Object_klass()) { | 256 result_oop->method_holder() == SystemDictionary::Object_klass()) { |
256 result_oop = NULL; | 257 result_oop = NULL; |
257 } | 258 } |
258 | 259 |
260 // Before considering default methods, check for an overpass in the | |
261 // current class if a method has not been found. | |
262 if (result_oop == NULL) { | |
263 result_oop = InstanceKlass::cast(klass())->find_method(name, signature); | |
264 } | |
265 | |
259 if (result_oop == NULL) { | 266 if (result_oop == NULL) { |
260 Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods(); | 267 Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods(); |
261 if (default_methods != NULL) { | 268 if (default_methods != NULL) { |
262 result_oop = InstanceKlass::find_method(default_methods, name, signature); | 269 result_oop = InstanceKlass::find_method(default_methods, name, signature); |
263 } | 270 } |
274 } | 281 } |
275 | 282 |
276 // returns first instance method | 283 // returns first instance method |
277 // Looks up method in classes, then looks up local default methods | 284 // 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) { | 285 void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { |
279 Method* result_oop = klass->uncached_lookup_method(name, signature); | 286 Method* result_oop = klass->uncached_lookup_method(name, signature, Klass::normal); |
280 result = methodHandle(THREAD, result_oop); | 287 result = methodHandle(THREAD, result_oop); |
281 while (!result.is_null() && result->is_static() && result->method_holder()->super() != NULL) { | 288 while (!result.is_null() && result->is_static() && result->method_holder()->super() != NULL) { |
282 KlassHandle super_klass = KlassHandle(THREAD, result->method_holder()->super()); | 289 KlassHandle super_klass = KlassHandle(THREAD, result->method_holder()->super()); |
283 result = methodHandle(THREAD, super_klass->uncached_lookup_method(name, signature)); | 290 result = methodHandle(THREAD, super_klass->uncached_lookup_method(name, signature, Klass::normal)); |
284 } | 291 } |
285 | 292 |
286 if (result.is_null()) { | 293 if (result.is_null()) { |
287 Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods(); | 294 Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods(); |
288 if (default_methods != NULL) { | 295 if (default_methods != NULL) { |
300 Symbol* signature = resolved_method->signature(); | 307 Symbol* signature = resolved_method->signature(); |
301 | 308 |
302 // First check in default method array | 309 // First check in default method array |
303 if (!resolved_method->is_abstract() && | 310 if (!resolved_method->is_abstract() && |
304 (InstanceKlass::cast(klass())->default_methods() != NULL)) { | 311 (InstanceKlass::cast(klass())->default_methods() != NULL)) { |
305 int index = InstanceKlass::find_method_index(InstanceKlass::cast(klass())->default_methods(), name, signature); | 312 int index = InstanceKlass::find_method_index(InstanceKlass::cast(klass())->default_methods(), name, signature, false); |
306 if (index >= 0 ) { | 313 if (index >= 0 ) { |
307 vtable_index = InstanceKlass::cast(klass())->default_vtable_indices()->at(index); | 314 vtable_index = InstanceKlass::cast(klass())->default_vtable_indices()->at(index); |
308 } | 315 } |
309 } | 316 } |
310 if (vtable_index == Method::invalid_vtable_index) { | 317 if (vtable_index == Method::invalid_vtable_index) { |
320 InstanceKlass *ik = InstanceKlass::cast(klass()); | 327 InstanceKlass *ik = InstanceKlass::cast(klass()); |
321 | 328 |
322 // Specify 'true' in order to skip default methods when searching the | 329 // Specify 'true' in order to skip default methods when searching the |
323 // interfaces. Function lookup_method_in_klasses() already looked for | 330 // interfaces. Function lookup_method_in_klasses() already looked for |
324 // the method in the default methods table. | 331 // the method in the default methods table. |
325 result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name, signature, true)); | 332 result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name, signature, Klass::skip_defaults)); |
326 } | 333 } |
327 | 334 |
328 void LinkResolver::lookup_polymorphic_method(methodHandle& result, | 335 void LinkResolver::lookup_polymorphic_method(methodHandle& result, |
329 KlassHandle klass, Symbol* name, Symbol* full_signature, | 336 KlassHandle klass, Symbol* name, Symbol* full_signature, |
330 KlassHandle current_klass, | 337 KlassHandle current_klass, |
562 method_signature), | 569 method_signature), |
563 nested_exception); | 570 nested_exception); |
564 } | 571 } |
565 } | 572 } |
566 | 573 |
567 // 5. check if method is concrete | 574 // 5. access checks, access checking may be turned off when calling from within the VM. |
568 if (resolved_method->is_abstract() && !resolved_klass->is_abstract()) { | |
569 ResourceMark rm(THREAD); | |
570 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), | |
571 Method::name_and_sig_as_C_string(resolved_klass(), | |
572 method_name, | |
573 method_signature)); | |
574 } | |
575 | |
576 // 6. access checks, access checking may be turned off when calling from within the VM. | |
577 if (check_access) { | 575 if (check_access) { |
578 assert(current_klass.not_null() , "current_klass should not be null"); | 576 assert(current_klass.not_null() , "current_klass should not be null"); |
579 | 577 |
580 // check if method can be accessed by the referring class | 578 // check if method can be accessed by the referring class |
581 check_method_accessability(current_klass, | 579 check_method_accessability(current_klass, |
646 Method::name_and_sig_as_C_string(resolved_klass(), | 644 Method::name_and_sig_as_C_string(resolved_klass(), |
647 method_name, | 645 method_name, |
648 method_signature)); | 646 method_signature)); |
649 } | 647 } |
650 } | 648 } |
651 | |
652 if (nostatics && resolved_method->is_static()) { | |
653 ResourceMark rm(THREAD); | |
654 char buf[200]; | |
655 jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s", Method::name_and_sig_as_C_string(resolved_klass(), | |
656 resolved_method->name(), | |
657 resolved_method->signature())); | |
658 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); | |
659 } | |
660 | |
661 | 649 |
662 if (check_access) { | 650 if (check_access) { |
663 // JDK8 adds non-public interface methods, and accessability check requirement | 651 // JDK8 adds non-public interface methods, and accessability check requirement |
664 assert(current_klass.not_null() , "current_klass should not be null"); | 652 assert(current_klass.not_null() , "current_klass should not be null"); |
665 | 653 |
700 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); | 688 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); |
701 } | 689 } |
702 } | 690 } |
703 } | 691 } |
704 | 692 |
693 if (nostatics && resolved_method->is_static()) { | |
694 ResourceMark rm(THREAD); | |
695 char buf[200]; | |
696 jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s", | |
697 Method::name_and_sig_as_C_string(resolved_klass(), | |
698 resolved_method->name(), resolved_method->signature())); | |
699 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); | |
700 } | |
701 | |
705 if (TraceItables && Verbose) { | 702 if (TraceItables && Verbose) { |
706 ResourceMark rm(THREAD); | 703 ResourceMark rm(THREAD); |
707 tty->print("invokeinterface resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ", | 704 tty->print("invokeinterface resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ", |
708 (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()), | 705 (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()), |
709 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()), | 706 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()), |
1635 &resolved_appendix, | 1632 &resolved_appendix, |
1636 &resolved_method_type, | 1633 &resolved_method_type, |
1637 THREAD); | 1634 THREAD); |
1638 if (HAS_PENDING_EXCEPTION) { | 1635 if (HAS_PENDING_EXCEPTION) { |
1639 if (TraceMethodHandles) { | 1636 if (TraceMethodHandles) { |
1640 tty->print_cr("invokedynamic throws BSME for "INTPTR_FORMAT, (void *)PENDING_EXCEPTION); | 1637 tty->print_cr("invokedynamic throws BSME for " INTPTR_FORMAT, p2i((void *)PENDING_EXCEPTION)); |
1641 PENDING_EXCEPTION->print(); | 1638 PENDING_EXCEPTION->print(); |
1642 } | 1639 } |
1643 if (PENDING_EXCEPTION->is_a(SystemDictionary::BootstrapMethodError_klass())) { | 1640 if (PENDING_EXCEPTION->is_a(SystemDictionary::BootstrapMethodError_klass())) { |
1644 // throw these guys, since they are already wrapped | 1641 // throw these guys, since they are already wrapped |
1645 return; | 1642 return; |