hotspot/src/share/vm/interpreter/linkResolver.cpp
changeset 14385 959bbcc16725
parent 13929 8da0dc50a6e4
child 14391 df0a1573d5bd
equal deleted inserted replaced
14289:aec758622b4b 14385:959bbcc16725
    21  * questions.
    21  * questions.
    22  *
    22  *
    23  */
    23  */
    24 
    24 
    25 #include "precompiled.hpp"
    25 #include "precompiled.hpp"
       
    26 #include "classfile/defaultMethods.hpp"
    26 #include "classfile/systemDictionary.hpp"
    27 #include "classfile/systemDictionary.hpp"
    27 #include "classfile/vmSymbols.hpp"
    28 #include "classfile/vmSymbols.hpp"
    28 #include "compiler/compileBroker.hpp"
    29 #include "compiler/compileBroker.hpp"
    29 #include "gc_interface/collectedHeap.inline.hpp"
    30 #include "gc_interface/collectedHeap.inline.hpp"
    30 #include "interpreter/bytecode.hpp"
    31 #include "interpreter/bytecode.hpp"
   402 
   403 
   403 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass,
   404 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass,
   404                                   Symbol* method_name, Symbol* method_signature,
   405                                   Symbol* method_name, Symbol* method_signature,
   405                                   KlassHandle current_klass, bool check_access, TRAPS) {
   406                                   KlassHandle current_klass, bool check_access, TRAPS) {
   406 
   407 
   407   // 1. check if klass is not interface
       
   408   if (resolved_klass->is_interface()) {
       
   409     ResourceMark rm(THREAD);
       
   410     char buf[200];
       
   411     jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected", Klass::cast(resolved_klass())->external_name());
       
   412     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
       
   413   }
       
   414 
       
   415   Handle nested_exception;
   408   Handle nested_exception;
   416 
   409 
   417   // 2. lookup method in resolved klass and its super klasses
   410   // 1. lookup method in resolved klass and its super klasses
   418   lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK);
   411   lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK);
   419 
   412 
   420   if (resolved_method.is_null()) { // not found in the class hierarchy
   413   if (resolved_method.is_null()) { // not found in the class hierarchy
   421     // 3. lookup method in all the interfaces implemented by the resolved klass
   414     // 2. lookup method in all the interfaces implemented by the resolved klass
   422     lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
   415     lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
   423 
   416 
   424     if (resolved_method.is_null()) {
   417     if (resolved_method.is_null()) {
   425       // JSR 292:  see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc
   418       // JSR 292:  see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc
   426       lookup_polymorphic_method(resolved_method, resolved_klass, method_name, method_signature,
   419       lookup_polymorphic_method(resolved_method, resolved_klass, method_name, method_signature,
   430         CLEAR_PENDING_EXCEPTION;
   423         CLEAR_PENDING_EXCEPTION;
   431       }
   424       }
   432     }
   425     }
   433 
   426 
   434     if (resolved_method.is_null()) {
   427     if (resolved_method.is_null()) {
   435       // 4. method lookup failed
   428       // 3. method lookup failed
   436       ResourceMark rm(THREAD);
   429       ResourceMark rm(THREAD);
   437       THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(),
   430       THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(),
   438                       Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   431                       Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
   439                                                               method_name,
   432                                                               method_name,
   440                                                               method_signature),
   433                                                               method_signature),
   441                       nested_exception);
   434                       nested_exception);
   442     }
   435     }
       
   436   }
       
   437 
       
   438   // 4. check if klass is not interface
       
   439   if (resolved_klass->is_interface() && resolved_method->is_abstract()) {
       
   440     ResourceMark rm(THREAD);
       
   441     char buf[200];
       
   442     jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected",
       
   443         resolved_klass()->external_name());
       
   444     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   443   }
   445   }
   444 
   446 
   445   // 5. check if method is concrete
   447   // 5. check if method is concrete
   446   if (resolved_method->is_abstract() && !resolved_klass->is_abstract()) {
   448   if (resolved_method->is_abstract() && !resolved_klass->is_abstract()) {
   447     ResourceMark rm(THREAD);
   449     ResourceMark rm(THREAD);
   741 // throws linktime exceptions
   743 // throws linktime exceptions
   742 void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method, KlassHandle resolved_klass,
   744 void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method, KlassHandle resolved_klass,
   743                                                    Symbol* method_name, Symbol* method_signature,
   745                                                    Symbol* method_name, Symbol* method_signature,
   744                                                    KlassHandle current_klass, bool check_access, TRAPS) {
   746                                                    KlassHandle current_klass, bool check_access, TRAPS) {
   745 
   747 
       
   748   if (resolved_klass->is_interface() && current_klass() != NULL) {
       
   749     // If the target class is a direct interface, treat this as a "super"
       
   750     // default call.
       
   751     //
       
   752     // If the current method is an overpass that happens to call a direct
       
   753     // super-interface's method, then we'll end up rerunning the default method
       
   754     // analysis even though we don't need to, but that's ok since it will end
       
   755     // up with the same answer.
       
   756     InstanceKlass* ik = InstanceKlass::cast(current_klass());
       
   757     Array<Klass*>* interfaces = ik->local_interfaces();
       
   758     int num_interfaces = interfaces->length();
       
   759     for (int index = 0; index < num_interfaces; index++) {
       
   760       if (interfaces->at(index) == resolved_klass()) {
       
   761         Method* method = DefaultMethods::find_super_default(current_klass(),
       
   762             resolved_klass(), method_name, method_signature, CHECK);
       
   763         resolved_method = methodHandle(THREAD, method);
       
   764         return;
       
   765       }
       
   766     }
       
   767   }
       
   768 
   746   resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
   769   resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
   747 
   770 
   748   // check if method name is <init>, that it is found in same klass as static type
   771   // check if method name is <init>, that it is found in same klass as static type
   749   if (resolved_method->name() == vmSymbols::object_initializer_name() &&
   772   if (resolved_method->name() == vmSymbols::object_initializer_name() &&
   750       resolved_method->method_holder() != resolved_klass()) {
   773       resolved_method->method_holder() != resolved_klass()) {
   782 
   805 
   783   // check if this is an old-style super call and do a new lookup if so
   806   // check if this is an old-style super call and do a new lookup if so
   784   { KlassHandle method_klass  = KlassHandle(THREAD,
   807   { KlassHandle method_klass  = KlassHandle(THREAD,
   785                                             resolved_method->method_holder());
   808                                             resolved_method->method_holder());
   786 
   809 
   787     if (check_access &&
   810     const bool direct_calling_default_method =
       
   811       resolved_klass() != NULL && resolved_method() != NULL &&
       
   812       resolved_klass->is_interface() && !resolved_method->is_abstract();
       
   813 
       
   814     if (!direct_calling_default_method &&
       
   815         check_access &&
   788         // a) check if ACC_SUPER flag is set for the current class
   816         // a) check if ACC_SUPER flag is set for the current class
   789         current_klass->is_super() &&
   817         current_klass->is_super() &&
   790         // b) check if the method class is a superclass of the current class (superclass relation is not reflexive!)
   818         // b) check if the method class is a superclass of the current class (superclass relation is not reflexive!)
   791         current_klass->is_subtype_of(method_klass()) && current_klass() != method_klass() &&
   819         current_klass->is_subtype_of(method_klass()) &&
       
   820         current_klass() != method_klass() &&
   792         // c) check if the method is not <init>
   821         // c) check if the method is not <init>
   793         resolved_method->name() != vmSymbols::object_initializer_name()) {
   822         resolved_method->name() != vmSymbols::object_initializer_name()) {
   794       // Lookup super method
   823       // Lookup super method
   795       KlassHandle super_klass(THREAD, current_klass->super());
   824       KlassHandle super_klass(THREAD, current_klass->super());
   796       lookup_instance_method_in_klasses(sel_method, super_klass,
   825       lookup_instance_method_in_klasses(sel_method, super_klass,