Mercurial > hg > graal-compiler
comparison src/share/vm/interpreter/linkResolver.cpp @ 14518:d8041d695d19
Merged with jdk9/dev/hotspot changeset 3812c088b945
author | twisti |
---|---|
date | Tue, 11 Mar 2014 18:45:59 -0700 |
parents | 02f27ecb4f3a f3959a2e0eee |
children | 4ca6dc0799b6 |
comparison
equal
deleted
inserted
replaced
14141:f97c5ec83832 | 14518:d8041d695d19 |
---|---|
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. |
298 int vtable_index = Method::invalid_vtable_index; | 298 int vtable_index = Method::invalid_vtable_index; |
299 Symbol* name = resolved_method->name(); | 299 Symbol* name = resolved_method->name(); |
300 Symbol* signature = resolved_method->signature(); | 300 Symbol* signature = resolved_method->signature(); |
301 | 301 |
302 // First check in default method array | 302 // First check in default method array |
303 if (!resolved_method->is_abstract() && | 303 if (!resolved_method->is_abstract() && |
304 (InstanceKlass::cast(klass())->default_methods() != NULL)) { | 304 (InstanceKlass::cast(klass())->default_methods() != NULL)) { |
305 int index = InstanceKlass::find_method_index(InstanceKlass::cast(klass())->default_methods(), name, signature); | 305 int index = InstanceKlass::find_method_index(InstanceKlass::cast(klass())->default_methods(), name, signature); |
306 if (index >= 0 ) { | 306 if (index >= 0 ) { |
307 vtable_index = InstanceKlass::cast(klass())->default_vtable_indices()->at(index); | 307 vtable_index = InstanceKlass::cast(klass())->default_vtable_indices()->at(index); |
308 } | 308 } |
316 return vtable_index; | 316 return vtable_index; |
317 } | 317 } |
318 | 318 |
319 void LinkResolver::lookup_method_in_interfaces(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { | 319 void LinkResolver::lookup_method_in_interfaces(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { |
320 InstanceKlass *ik = InstanceKlass::cast(klass()); | 320 InstanceKlass *ik = InstanceKlass::cast(klass()); |
321 result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name, signature)); | 321 |
322 // Specify 'true' in order to skip default methods when searching the | |
323 // interfaces. Function lookup_method_in_klasses() already looked for | |
324 // the method in the default methods table. | |
325 result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name, signature, true)); | |
322 } | 326 } |
323 | 327 |
324 void LinkResolver::lookup_polymorphic_method(methodHandle& result, | 328 void LinkResolver::lookup_polymorphic_method(methodHandle& result, |
325 KlassHandle klass, Symbol* name, Symbol* full_signature, | 329 KlassHandle klass, Symbol* name, Symbol* full_signature, |
326 KlassHandle current_klass, | 330 KlassHandle current_klass, |
558 method_signature), | 562 method_signature), |
559 nested_exception); | 563 nested_exception); |
560 } | 564 } |
561 } | 565 } |
562 | 566 |
563 // 5. check if method is concrete | 567 // 5. access checks, access checking may be turned off when calling from within the VM. |
564 if (resolved_method->is_abstract() && !resolved_klass->is_abstract()) { | |
565 ResourceMark rm(THREAD); | |
566 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), | |
567 Method::name_and_sig_as_C_string(resolved_klass(), | |
568 method_name, | |
569 method_signature)); | |
570 } | |
571 | |
572 // 6. access checks, access checking may be turned off when calling from within the VM. | |
573 if (check_access) { | 568 if (check_access) { |
574 assert(current_klass.not_null() , "current_klass should not be null"); | 569 assert(current_klass.not_null() , "current_klass should not be null"); |
575 | 570 |
576 // check if method can be accessed by the referring class | 571 // check if method can be accessed by the referring class |
577 check_method_accessability(current_klass, | 572 check_method_accessability(current_klass, |
618 Symbol* method_signature, | 613 Symbol* method_signature, |
619 KlassHandle current_klass, | 614 KlassHandle current_klass, |
620 bool check_access, | 615 bool check_access, |
621 bool nostatics, TRAPS) { | 616 bool nostatics, TRAPS) { |
622 | 617 |
623 // check if klass is interface | 618 // check if klass is interface |
624 if (!resolved_klass->is_interface()) { | 619 if (!resolved_klass->is_interface()) { |
625 ResourceMark rm(THREAD); | 620 ResourceMark rm(THREAD); |
626 char buf[200]; | 621 char buf[200]; |
627 jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name()); | 622 jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name()); |
628 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); | 623 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); |
642 Method::name_and_sig_as_C_string(resolved_klass(), | 637 Method::name_and_sig_as_C_string(resolved_klass(), |
643 method_name, | 638 method_name, |
644 method_signature)); | 639 method_signature)); |
645 } | 640 } |
646 } | 641 } |
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())); | |
654 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); | |
655 } | |
656 | |
657 | 642 |
658 if (check_access) { | 643 if (check_access) { |
659 // JDK8 adds non-public interface methods, and accessability check requirement | 644 // JDK8 adds non-public interface methods, and accessability check requirement |
660 assert(current_klass.not_null() , "current_klass should not be null"); | 645 assert(current_klass.not_null() , "current_klass should not be null"); |
661 | 646 |
696 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); | 681 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); |
697 } | 682 } |
698 } | 683 } |
699 } | 684 } |
700 | 685 |
686 if (nostatics && resolved_method->is_static()) { | |
687 ResourceMark rm(THREAD); | |
688 char buf[200]; | |
689 jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s", | |
690 Method::name_and_sig_as_C_string(resolved_klass(), | |
691 resolved_method->name(), resolved_method->signature())); | |
692 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); | |
693 } | |
694 | |
701 if (TraceItables && Verbose) { | 695 if (TraceItables && Verbose) { |
702 ResourceMark rm(THREAD); | 696 ResourceMark rm(THREAD); |
703 tty->print("invokeinterface resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ", | 697 tty->print("invokeinterface resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ", |
704 (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()), | 698 (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()), |
705 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()), | 699 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()), |
1289 jio_snprintf(buf, sizeof(buf), "Class %s does not implement the requested interface %s", | 1283 jio_snprintf(buf, sizeof(buf), "Class %s does not implement the requested interface %s", |
1290 recv_klass()->external_name(), | 1284 recv_klass()->external_name(), |
1291 resolved_klass()->external_name()); | 1285 resolved_klass()->external_name()); |
1292 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); | 1286 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); |
1293 } | 1287 } |
1288 | |
1294 // do lookup based on receiver klass | 1289 // do lookup based on receiver klass |
1295 methodHandle sel_method; | 1290 methodHandle sel_method; |
1291 // This search must match the linktime preparation search for itable initialization | |
1292 // to correctly enforce loader constraints for interface method inheritance | |
1296 lookup_instance_method_in_klasses(sel_method, recv_klass, | 1293 lookup_instance_method_in_klasses(sel_method, recv_klass, |
1297 resolved_method->name(), | 1294 resolved_method->name(), |
1298 resolved_method->signature(), CHECK); | 1295 resolved_method->signature(), CHECK); |
1299 if (sel_method.is_null() && !check_null_and_abstract) { | 1296 if (sel_method.is_null() && !check_null_and_abstract) { |
1300 // In theory this is a harmless placeholder value, but | 1297 // In theory this is a harmless placeholder value, but |