8026066: ICCE for invokeinterface static

Tue, 03 Dec 2013 08:36:15 -0800

author
acorn
date
Tue, 03 Dec 2013 08:36:15 -0800
changeset 6144
7a58803b5069
parent 6143
6ce6a0d23467
child 6145
379f11bc04fc
child 6146
c8c2d6b82499

8026066: ICCE for invokeinterface static
Reviewed-by: coleenp, lfoltan, hseigel

src/share/vm/interpreter/linkResolver.cpp file | annotate | diff | comparison | revisions
src/share/vm/interpreter/linkResolver.hpp file | annotate | diff | comparison | revisions
test/TEST.groups file | annotate | diff | comparison | revisions
test/runtime/8024804/RegisterNatives.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/interpreter/linkResolver.cpp	Mon Dec 02 11:42:10 2013 +0100
     1.2 +++ b/src/share/vm/interpreter/linkResolver.cpp	Tue Dec 03 08:36:15 2013 -0800
     1.3 @@ -242,7 +242,7 @@
     1.4  
     1.5  // Look up method in klasses, including static methods
     1.6  // Then look up local default methods
     1.7 -void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
     1.8 +void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, TRAPS) {
     1.9    Method* result_oop = klass->uncached_lookup_method(name, signature);
    1.10    if (result_oop == NULL) {
    1.11      Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods();
    1.12 @@ -251,7 +251,7 @@
    1.13      }
    1.14    }
    1.15  
    1.16 -  if (EnableInvokeDynamic && result_oop != NULL) {
    1.17 +  if (checkpolymorphism && EnableInvokeDynamic && result_oop != NULL) {
    1.18      vmIntrinsics::ID iid = result_oop->intrinsic_id();
    1.19      if (MethodHandles::is_signature_polymorphic(iid)) {
    1.20        // Do not link directly to these.  The VM must produce a synthetic one using lookup_polymorphic_method.
    1.21 @@ -503,11 +503,14 @@
    1.22    }
    1.23  
    1.24    if (code == Bytecodes::_invokeinterface) {
    1.25 -    resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
    1.26 +    resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
    1.27    } else if (code == Bytecodes::_invokevirtual) {
    1.28      resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
    1.29 +  } else if (!resolved_klass->is_interface()) {
    1.30 +    resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, false, CHECK);
    1.31    } else {
    1.32 -    resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, false, CHECK);
    1.33 +    bool nostatics = (code == Bytecodes::_invokestatic) ? false : true;
    1.34 +    resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, nostatics, CHECK);
    1.35    }
    1.36  }
    1.37  
    1.38 @@ -528,7 +531,7 @@
    1.39    }
    1.40  
    1.41    // 2. lookup method in resolved klass and its super klasses
    1.42 -  lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK);
    1.43 +  lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, true, CHECK);
    1.44  
    1.45    if (resolved_method.is_null()) { // not found in the class hierarchy
    1.46      // 3. lookup method in all the interfaces implemented by the resolved klass
    1.47 @@ -612,7 +615,8 @@
    1.48                                              Symbol* method_name,
    1.49                                              Symbol* method_signature,
    1.50                                              KlassHandle current_klass,
    1.51 -                                            bool check_access, TRAPS) {
    1.52 +                                            bool check_access,
    1.53 +                                            bool nostatics, TRAPS) {
    1.54  
    1.55   // check if klass is interface
    1.56    if (!resolved_klass->is_interface()) {
    1.57 @@ -623,7 +627,8 @@
    1.58    }
    1.59  
    1.60    // lookup method in this interface or its super, java.lang.Object
    1.61 -  lookup_instance_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK);
    1.62 +  // JDK8: also look for static methods
    1.63 +  lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, false, CHECK);
    1.64  
    1.65    if (resolved_method.is_null()) {
    1.66      // lookup method in all the super-interfaces
    1.67 @@ -638,6 +643,16 @@
    1.68      }
    1.69    }
    1.70  
    1.71 +  if (nostatics && resolved_method->is_static()) {
    1.72 +    ResourceMark rm(THREAD);
    1.73 +    char buf[200];
    1.74 +    jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s", Method::name_and_sig_as_C_string(resolved_klass(),
    1.75 +                                                      resolved_method->name(),
    1.76 +                                                      resolved_method->signature()));
    1.77 +    THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
    1.78 +  }
    1.79 +
    1.80 +
    1.81    if (check_access) {
    1.82      // JDK8 adds non-public interface methods, and accessability check requirement
    1.83      assert(current_klass.not_null() , "current_klass should not be null");
    1.84 @@ -864,7 +879,11 @@
    1.85                                                    Symbol* method_name, Symbol* method_signature,
    1.86                                                    KlassHandle current_klass, bool check_access, TRAPS) {
    1.87  
    1.88 -  resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK);
    1.89 +  if (!resolved_klass->is_interface()) {
    1.90 +    resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK);
    1.91 +  } else {
    1.92 +    resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK);
    1.93 +  }
    1.94    assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier");
    1.95  
    1.96    // check if static
    1.97 @@ -898,7 +917,11 @@
    1.98    // and the selected method is recalculated relative to the direct superclass
    1.99    // superinterface.method, which explicitly does not check shadowing
   1.100  
   1.101 -  resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK);
   1.102 +  if (!resolved_klass->is_interface()) {
   1.103 +    resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK);
   1.104 +  } else {
   1.105 +    resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, true, CHECK);
   1.106 +  }
   1.107  
   1.108    // check if method name is <init>, that it is found in same klass as static type
   1.109    if (resolved_method->name() == vmSymbols::object_initializer_name() &&
   1.110 @@ -1219,7 +1242,7 @@
   1.111  void LinkResolver::linktime_resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name,
   1.112                                                       Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) {
   1.113    // normal interface method resolution
   1.114 -  resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
   1.115 +  resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, true, CHECK);
   1.116  
   1.117    assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
   1.118    assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
     2.1 --- a/src/share/vm/interpreter/linkResolver.hpp	Mon Dec 02 11:42:10 2013 +0100
     2.2 +++ b/src/share/vm/interpreter/linkResolver.hpp	Tue Dec 03 08:36:15 2013 -0800
     2.3 @@ -124,7 +124,7 @@
     2.4    friend class klassItable;
     2.5  
     2.6   private:
     2.7 -  static void lookup_method_in_klasses          (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
     2.8 +  static void lookup_method_in_klasses          (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, TRAPS);
     2.9    static void lookup_instance_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
    2.10    static void lookup_method_in_interfaces       (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
    2.11    static void lookup_polymorphic_method         (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature,
    2.12 @@ -134,7 +134,7 @@
    2.13  
    2.14    static void resolve_pool  (KlassHandle& resolved_klass, Symbol*& method_name, Symbol*& method_signature, KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS);
    2.15  
    2.16 -  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.17 +  static void resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool nostatics, TRAPS);
    2.18    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.19  
    2.20    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);
     3.1 --- a/test/TEST.groups	Mon Dec 02 11:42:10 2013 +0100
     3.2 +++ b/test/TEST.groups	Tue Dec 03 08:36:15 2013 -0800
     3.3 @@ -70,7 +70,6 @@
     3.4    runtime/7107135/Test7107135.sh \
     3.5    runtime/7158988/FieldMonitor.java \
     3.6    runtime/7194254/Test7194254.java \
     3.7 -  runtime/8026365/InvokeSpecialAnonTest.java \
     3.8    runtime/jsig/Test8017498.sh \
     3.9    runtime/Metaspace/FragmentMetaspace.java \
    3.10    runtime/NMT/BaselineWithParameter.java \
     4.1 --- a/test/runtime/8024804/RegisterNatives.java	Mon Dec 02 11:42:10 2013 +0100
     4.2 +++ b/test/runtime/8024804/RegisterNatives.java	Tue Dec 03 08:36:15 2013 -0800
     4.3 @@ -22,6 +22,7 @@
     4.4   */
     4.5  
     4.6  /*
     4.7 + * @ignore 8028741
     4.8   * @test
     4.9   * @bug 8024804
    4.10   * @summary registerNatives() interface resolution should receive IAE

mercurial