8026299: invokespecial gets ICCE when it should get AME.

Mon, 14 Oct 2013 21:52:42 -0400

author
acorn
date
Mon, 14 Oct 2013 21:52:42 -0400
changeset 5897
2f8728d92483
parent 5896
d37a0525c0fe
child 5898
f509b8f4699b

8026299: invokespecial gets ICCE when it should get AME.
Reviewed-by: ccheung, coleenp

src/share/vm/interpreter/linkResolver.cpp file | annotate | diff | comparison | revisions
src/share/vm/interpreter/linkResolver.hpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/interpreter/linkResolver.cpp	Sat Oct 12 15:39:16 2013 -0400
     1.2 +++ b/src/share/vm/interpreter/linkResolver.cpp	Mon Oct 14 21:52:42 2013 -0400
     1.3 @@ -454,7 +454,7 @@
     1.4      Symbol* method_name = vmSymbols::invoke_name();
     1.5      Symbol* method_signature = pool->signature_ref_at(index);
     1.6      KlassHandle  current_klass(THREAD, pool->pool_holder());
     1.7 -    resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
     1.8 +    resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, false, CHECK);
     1.9      return;
    1.10    }
    1.11  
    1.12 @@ -476,22 +476,34 @@
    1.13  
    1.14    if (code == Bytecodes::_invokeinterface) {
    1.15      resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
    1.16 +  } else if (code == Bytecodes::_invokevirtual) {
    1.17 +    resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
    1.18    } else {
    1.19 -    resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
    1.20 +    resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, false, CHECK);
    1.21    }
    1.22  }
    1.23  
    1.24  void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass,
    1.25                                    Symbol* method_name, Symbol* method_signature,
    1.26 -                                  KlassHandle current_klass, bool check_access, TRAPS) {
    1.27 +                                  KlassHandle current_klass, bool check_access,
    1.28 +                                  bool require_methodref, TRAPS) {
    1.29  
    1.30    Handle nested_exception;
    1.31  
    1.32 -  // 1. lookup method in resolved klass and its super klasses
    1.33 +  // 1. check if methodref required, that resolved_klass is not interfacemethodref
    1.34 +  if (require_methodref && resolved_klass->is_interface()) {
    1.35 +    ResourceMark rm(THREAD);
    1.36 +    char buf[200];
    1.37 +    jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected",
    1.38 +        resolved_klass()->external_name());
    1.39 +    THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
    1.40 +  }
    1.41 +
    1.42 +  // 2. lookup method in resolved klass and its super klasses
    1.43    lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK);
    1.44  
    1.45    if (resolved_method.is_null()) { // not found in the class hierarchy
    1.46 -    // 2. lookup method in all the interfaces implemented by the resolved klass
    1.47 +    // 3. lookup method in all the interfaces implemented by the resolved klass
    1.48      lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
    1.49  
    1.50      if (resolved_method.is_null()) {
    1.51 @@ -505,7 +517,7 @@
    1.52      }
    1.53  
    1.54      if (resolved_method.is_null()) {
    1.55 -      // 3. method lookup failed
    1.56 +      // 4. method lookup failed
    1.57        ResourceMark rm(THREAD);
    1.58        THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(),
    1.59                        Method::name_and_sig_as_C_string(resolved_klass(),
    1.60 @@ -515,15 +527,6 @@
    1.61      }
    1.62    }
    1.63  
    1.64 -  // 4. check if klass is not interface
    1.65 -  if (resolved_klass->is_interface() && resolved_method->is_abstract()) {
    1.66 -    ResourceMark rm(THREAD);
    1.67 -    char buf[200];
    1.68 -    jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected",
    1.69 -        resolved_klass()->external_name());
    1.70 -    THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
    1.71 -  }
    1.72 -
    1.73    // 5. check if method is concrete
    1.74    if (resolved_method->is_abstract() && !resolved_klass->is_abstract()) {
    1.75      ResourceMark rm(THREAD);
    1.76 @@ -833,7 +836,7 @@
    1.77                                                    Symbol* method_name, Symbol* method_signature,
    1.78                                                    KlassHandle current_klass, bool check_access, TRAPS) {
    1.79  
    1.80 -  resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
    1.81 +  resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK);
    1.82    assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier");
    1.83  
    1.84    // check if static
    1.85 @@ -867,7 +870,7 @@
    1.86    // and the selected method is recalculated relative to the direct superclass
    1.87    // superinterface.method, which explicitly does not check shadowing
    1.88  
    1.89 -  resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
    1.90 +  resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK);
    1.91  
    1.92    // check if method name is <init>, that it is found in same klass as static type
    1.93    if (resolved_method->name() == vmSymbols::object_initializer_name() &&
    1.94 @@ -1013,7 +1016,7 @@
    1.95                                                     Symbol* method_name, Symbol* method_signature,
    1.96                                                     KlassHandle current_klass, bool check_access, TRAPS) {
    1.97    // normal method resolution
    1.98 -  resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
    1.99 +  resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, true, CHECK);
   1.100  
   1.101    assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
   1.102    assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
     2.1 --- a/src/share/vm/interpreter/linkResolver.hpp	Sat Oct 12 15:39:16 2013 -0400
     2.2 +++ b/src/share/vm/interpreter/linkResolver.hpp	Mon Oct 14 21:52:42 2013 -0400
     2.3 @@ -136,7 +136,7 @@
     2.4    static void resolve_pool  (KlassHandle& resolved_klass, Symbol*& method_name, Symbol*& method_signature, KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS);
     2.5  
     2.6    static void resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);
     2.7 -  static void resolve_method          (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);
     2.8 +  static void resolve_method          (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool require_methodref, TRAPS);
     2.9  
    2.10    static void linktime_resolve_static_method    (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);
    2.11    static void linktime_resolve_special_method   (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);

mercurial