src/share/vm/interpreter/linkResolver.cpp

changeset 6830
54bc75c144b0
parent 6818
096a7e12d63f
parent 6680
78bbf4d43a14
child 6876
710a3c8b516e
child 7499
9906d432d6db
     1.1 --- a/src/share/vm/interpreter/linkResolver.cpp	Wed May 28 08:09:26 2014 -0400
     1.2 +++ b/src/share/vm/interpreter/linkResolver.cpp	Thu May 29 13:14:25 2014 -0700
     1.3 @@ -243,7 +243,8 @@
     1.4  // Look up method in klasses, including static methods
     1.5  // Then look up local default methods
     1.6  void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, bool in_imethod_resolve, TRAPS) {
     1.7 -  Method* result_oop = klass->uncached_lookup_method(name, signature);
     1.8 +  // Ignore overpasses so statics can be found during resolution
     1.9 +  Method* result_oop = klass->uncached_lookup_method(name, signature, Klass::skip_overpass);
    1.10  
    1.11    if (klass->oop_is_array()) {
    1.12      // Only consider klass and super klass for arrays
    1.13 @@ -262,6 +263,12 @@
    1.14      result_oop = NULL;
    1.15    }
    1.16  
    1.17 +  // Before considering default methods, check for an overpass in the
    1.18 +  // current class if a method has not been found.
    1.19 +  if (result_oop == NULL) {
    1.20 +    result_oop = InstanceKlass::cast(klass())->find_method(name, signature);
    1.21 +  }
    1.22 +
    1.23    if (result_oop == NULL) {
    1.24      Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods();
    1.25      if (default_methods != NULL) {
    1.26 @@ -282,11 +289,11 @@
    1.27  // returns first instance method
    1.28  // Looks up method in classes, then looks up local default methods
    1.29  void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
    1.30 -  Method* result_oop = klass->uncached_lookup_method(name, signature);
    1.31 +  Method* result_oop = klass->uncached_lookup_method(name, signature, Klass::normal);
    1.32    result = methodHandle(THREAD, result_oop);
    1.33    while (!result.is_null() && result->is_static() && result->method_holder()->super() != NULL) {
    1.34      KlassHandle super_klass = KlassHandle(THREAD, result->method_holder()->super());
    1.35 -    result = methodHandle(THREAD, super_klass->uncached_lookup_method(name, signature));
    1.36 +    result = methodHandle(THREAD, super_klass->uncached_lookup_method(name, signature, Klass::normal));
    1.37    }
    1.38  
    1.39    if (klass->oop_is_array()) {
    1.40 @@ -313,7 +320,7 @@
    1.41    // First check in default method array
    1.42    if (!resolved_method->is_abstract() &&
    1.43      (InstanceKlass::cast(klass())->default_methods() != NULL)) {
    1.44 -    int index = InstanceKlass::find_method_index(InstanceKlass::cast(klass())->default_methods(), name, signature);
    1.45 +    int index = InstanceKlass::find_method_index(InstanceKlass::cast(klass())->default_methods(), name, signature, false);
    1.46      if (index >= 0 ) {
    1.47        vtable_index = InstanceKlass::cast(klass())->default_vtable_indices()->at(index);
    1.48      }
    1.49 @@ -333,7 +340,7 @@
    1.50    // Specify 'true' in order to skip default methods when searching the
    1.51    // interfaces.  Function lookup_method_in_klasses() already looked for
    1.52    // the method in the default methods table.
    1.53 -  result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name, signature, true));
    1.54 +  result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name, signature, Klass::skip_defaults));
    1.55  }
    1.56  
    1.57  void LinkResolver::lookup_polymorphic_method(methodHandle& result,
    1.58 @@ -575,16 +582,7 @@
    1.59                      nested_exception);
    1.60    }
    1.61  
    1.62 -  // 5. check if method is concrete
    1.63 -  if (resolved_method->is_abstract() && !resolved_klass->is_abstract()) {
    1.64 -    ResourceMark rm(THREAD);
    1.65 -    THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
    1.66 -              Method::name_and_sig_as_C_string(resolved_klass(),
    1.67 -                                                      method_name,
    1.68 -                                                      method_signature));
    1.69 -  }
    1.70 -
    1.71 -  // 6. access checks, access checking may be turned off when calling from within the VM.
    1.72 +  // 5. access checks, access checking may be turned off when calling from within the VM.
    1.73    if (check_access) {
    1.74      assert(current_klass.not_null() , "current_klass should not be null");
    1.75  
    1.76 @@ -661,16 +659,6 @@
    1.77                                                        method_signature));
    1.78    }
    1.79  
    1.80 -  if (nostatics && resolved_method->is_static()) {
    1.81 -    ResourceMark rm(THREAD);
    1.82 -    char buf[200];
    1.83 -    jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s", Method::name_and_sig_as_C_string(resolved_klass(),
    1.84 -                                                      resolved_method->name(),
    1.85 -                                                      resolved_method->signature()));
    1.86 -    THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
    1.87 -  }
    1.88 -
    1.89 -
    1.90    if (check_access) {
    1.91      // JDK8 adds non-public interface methods, and accessability check requirement
    1.92      assert(current_klass.not_null() , "current_klass should not be null");
    1.93 @@ -714,6 +702,15 @@
    1.94      }
    1.95    }
    1.96  
    1.97 +  if (nostatics && resolved_method->is_static()) {
    1.98 +    ResourceMark rm(THREAD);
    1.99 +    char buf[200];
   1.100 +    jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s",
   1.101 +                 Method::name_and_sig_as_C_string(resolved_klass(),
   1.102 +                 resolved_method->name(), resolved_method->signature()));
   1.103 +    THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   1.104 +  }
   1.105 +
   1.106    if (TraceItables && Verbose) {
   1.107      ResourceMark rm(THREAD);
   1.108      tty->print("invokeinterface resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ",
   1.109 @@ -1645,7 +1642,7 @@
   1.110                                                       THREAD);
   1.111    if (HAS_PENDING_EXCEPTION) {
   1.112      if (TraceMethodHandles) {
   1.113 -      tty->print_cr("invokedynamic throws BSME for "INTPTR_FORMAT, (void *)PENDING_EXCEPTION);
   1.114 +      tty->print_cr("invokedynamic throws BSME for " INTPTR_FORMAT, p2i((void *)PENDING_EXCEPTION));
   1.115        PENDING_EXCEPTION->print();
   1.116      }
   1.117      if (PENDING_EXCEPTION->is_a(SystemDictionary::BootstrapMethodError_klass())) {

mercurial