8087342: Crash in klassItable::initialize_itable_for_interface

Thu, 02 Feb 2017 00:29:28 +0000

author
dbuck
date
Thu, 02 Feb 2017 00:29:28 +0000
changeset 8716
619700f41f8e
parent 8715
567e410935e5
child 8717
77d9c9da7188

8087342: Crash in klassItable::initialize_itable_for_interface
Summary: Fix method searches to handle static, private instance and overpass
Reviewed-by: acorn

src/share/vm/classfile/verifier.cpp file | annotate | diff | comparison | revisions
src/share/vm/interpreter/linkResolver.cpp file | annotate | diff | comparison | revisions
src/share/vm/oops/arrayKlass.cpp file | annotate | diff | comparison | revisions
src/share/vm/oops/arrayKlass.hpp file | annotate | diff | comparison | revisions
src/share/vm/oops/instanceKlass.cpp file | annotate | diff | comparison | revisions
src/share/vm/oops/instanceKlass.hpp file | annotate | diff | comparison | revisions
src/share/vm/oops/klass.cpp file | annotate | diff | comparison | revisions
src/share/vm/oops/klass.hpp file | annotate | diff | comparison | revisions
src/share/vm/oops/klassVtable.cpp file | annotate | diff | comparison | revisions
src/share/vm/prims/jvm.cpp file | annotate | diff | comparison | revisions
src/share/vm/prims/nativeLookup.cpp file | annotate | diff | comparison | revisions
test/runtime/lambda-features/TestStaticandInstance.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/classfile/verifier.cpp	Fri Jan 20 16:22:39 2017 +0000
     1.2 +++ b/src/share/vm/classfile/verifier.cpp	Thu Feb 02 00:29:28 2017 +0000
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -1969,7 +1969,7 @@
    1.11    InstanceKlass* target_instance = InstanceKlass::cast(target_class);
    1.12    fieldDescriptor fd;
    1.13    if (is_method) {
    1.14 -    Method* m = target_instance->uncached_lookup_method(field_name, field_sig, Klass::normal);
    1.15 +    Method* m = target_instance->uncached_lookup_method(field_name, field_sig, Klass::find_overpass);
    1.16      if (m != NULL && m->is_protected()) {
    1.17        if (!this_class->is_same_class_package(m->method_holder())) {
    1.18          return true;
    1.19 @@ -2539,7 +2539,7 @@
    1.20        Klass* ref_klass = load_class(ref_class_type.name(), CHECK);
    1.21        Method* m = InstanceKlass::cast(ref_klass)->uncached_lookup_method(
    1.22          vmSymbols::object_initializer_name(),
    1.23 -        cp->signature_ref_at(bcs->get_index_u2()), Klass::normal);
    1.24 +        cp->signature_ref_at(bcs->get_index_u2()), Klass::find_overpass);
    1.25        // Do nothing if method is not found.  Let resolution detect the error.
    1.26        if (m != NULL) {
    1.27          instanceKlassHandle mh(THREAD, m->method_holder());
     2.1 --- a/src/share/vm/interpreter/linkResolver.cpp	Fri Jan 20 16:22:39 2017 +0000
     2.2 +++ b/src/share/vm/interpreter/linkResolver.cpp	Thu Feb 02 00:29:28 2017 +0000
     2.3 @@ -1,5 +1,5 @@
     2.4  /*
     2.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
     2.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
     2.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.8   *
     2.9   * This code is free software; you can redistribute it and/or modify it
    2.10 @@ -289,11 +289,11 @@
    2.11  // returns first instance method
    2.12  // Looks up method in classes, then looks up local default methods
    2.13  void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
    2.14 -  Method* result_oop = klass->uncached_lookup_method(name, signature, Klass::normal);
    2.15 +  Method* result_oop = klass->uncached_lookup_method(name, signature, Klass::find_overpass);
    2.16    result = methodHandle(THREAD, result_oop);
    2.17    while (!result.is_null() && result->is_static() && result->method_holder()->super() != NULL) {
    2.18      KlassHandle super_klass = KlassHandle(THREAD, result->method_holder()->super());
    2.19 -    result = methodHandle(THREAD, super_klass->uncached_lookup_method(name, signature, Klass::normal));
    2.20 +    result = methodHandle(THREAD, super_klass->uncached_lookup_method(name, signature, Klass::find_overpass));
    2.21    }
    2.22  
    2.23    if (klass->oop_is_array()) {
    2.24 @@ -320,7 +320,9 @@
    2.25    // First check in default method array
    2.26    if (!resolved_method->is_abstract() &&
    2.27      (InstanceKlass::cast(klass())->default_methods() != NULL)) {
    2.28 -    int index = InstanceKlass::find_method_index(InstanceKlass::cast(klass())->default_methods(), name, signature, false, false);
    2.29 +    int index = InstanceKlass::find_method_index(InstanceKlass::cast(klass())->default_methods(),
    2.30 +                                                 name, signature, Klass::find_overpass,
    2.31 +                                                 Klass::find_static, Klass::find_private);
    2.32      if (index >= 0 ) {
    2.33        vtable_index = InstanceKlass::cast(klass())->default_vtable_indices()->at(index);
    2.34      }
    2.35 @@ -1184,7 +1186,7 @@
    2.36    assert(resolved_method->method_holder()->is_linked(), "must be linked");
    2.37  
    2.38    // do lookup based on receiver klass using the vtable index
    2.39 -  if (resolved_method->method_holder()->is_interface()) { // miranda method
    2.40 +  if (resolved_method->method_holder()->is_interface()) { // default or miranda method
    2.41      vtable_index = vtable_index_of_interface_method(resolved_klass,
    2.42                             resolved_method);
    2.43      assert(vtable_index >= 0 , "we should have valid vtable index at this point");
    2.44 @@ -1193,7 +1195,7 @@
    2.45      selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index));
    2.46    } else {
    2.47      // at this point we are sure that resolved_method is virtual and not
    2.48 -    // a miranda method; therefore, it must have a valid vtable index.
    2.49 +    // a default or miranda method; therefore, it must have a valid vtable index.
    2.50      assert(!resolved_method->has_itable_index(), "");
    2.51      vtable_index = resolved_method->vtable_index();
    2.52      // We could get a negative vtable_index for final methods,
     3.1 --- a/src/share/vm/oops/arrayKlass.cpp	Fri Jan 20 16:22:39 2017 +0000
     3.2 +++ b/src/share/vm/oops/arrayKlass.cpp	Thu Feb 02 00:29:28 2017 +0000
     3.3 @@ -1,5 +1,5 @@
     3.4  /*
     3.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
     3.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
     3.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.8   *
     3.9   * This code is free software; you can redistribute it and/or modify it
    3.10 @@ -71,10 +71,13 @@
    3.11    return super()->find_field(name, sig, fd);
    3.12  }
    3.13  
    3.14 -Method* ArrayKlass::uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const {
    3.15 +Method* ArrayKlass::uncached_lookup_method(Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode) const {
    3.16    // There are no methods in an array klass but the super class (Object) has some
    3.17    assert(super(), "super klass must be present");
    3.18 -  return super()->uncached_lookup_method(name, signature, mode);
    3.19 +  // Always ignore overpass methods in superclasses, although technically the
    3.20 +  // super klass of an array, (j.l.Object) should not have
    3.21 +  // any overpass methods present.
    3.22 +  return super()->uncached_lookup_method(name, signature, Klass::skip_overpass);
    3.23  }
    3.24  
    3.25  ArrayKlass::ArrayKlass(Symbol* name) {
     4.1 --- a/src/share/vm/oops/arrayKlass.hpp	Fri Jan 20 16:22:39 2017 +0000
     4.2 +++ b/src/share/vm/oops/arrayKlass.hpp	Thu Feb 02 00:29:28 2017 +0000
     4.3 @@ -1,5 +1,5 @@
     4.4  /*
     4.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
     4.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
     4.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.8   *
     4.9   * This code is free software; you can redistribute it and/or modify it
    4.10 @@ -90,7 +90,7 @@
    4.11    Klass* find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const;
    4.12  
    4.13    // Lookup operations
    4.14 -  Method* uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const;
    4.15 +  Method* uncached_lookup_method(Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode) const;
    4.16  
    4.17    // Casting from Klass*
    4.18    static ArrayKlass* cast(Klass* k) {
     5.1 --- a/src/share/vm/oops/instanceKlass.cpp	Fri Jan 20 16:22:39 2017 +0000
     5.2 +++ b/src/share/vm/oops/instanceKlass.cpp	Thu Feb 02 00:29:28 2017 +0000
     5.3 @@ -1,5 +1,5 @@
     5.4  /*
     5.5 - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
     5.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
     5.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.8   *
     5.9   * This code is free software; you can redistribute it and/or modify it
    5.10 @@ -1475,18 +1475,23 @@
    5.11  
    5.12  // find_method looks up the name/signature in the local methods array
    5.13  Method* InstanceKlass::find_method(Symbol* name, Symbol* signature) const {
    5.14 -  return find_method_impl(name, signature, false);
    5.15 +  return find_method_impl(name, signature, find_overpass, find_static, find_private);
    5.16  }
    5.17  
    5.18 -Method* InstanceKlass::find_method_impl(Symbol* name, Symbol* signature, bool skipping_overpass) const {
    5.19 -  return InstanceKlass::find_method_impl(methods(), name, signature, skipping_overpass, false);
    5.20 +Method* InstanceKlass::find_method_impl(Symbol* name, Symbol* signature,
    5.21 +                                        OverpassLookupMode overpass_mode,
    5.22 +                                        StaticLookupMode static_mode,
    5.23 +                                        PrivateLookupMode private_mode) const {
    5.24 +  return InstanceKlass::find_method_impl(methods(), name, signature, overpass_mode, static_mode, private_mode);
    5.25  }
    5.26  
    5.27  // find_instance_method looks up the name/signature in the local methods array
    5.28  // and skips over static methods
    5.29  Method* InstanceKlass::find_instance_method(
    5.30      Array<Method*>* methods, Symbol* name, Symbol* signature) {
    5.31 -  Method* meth = InstanceKlass::find_method_impl(methods, name, signature, false, true);
    5.32 +  Method* meth = InstanceKlass::find_method_impl(methods, name, signature,
    5.33 +                                                 find_overpass, skip_static, find_private);
    5.34 +  assert(((meth == NULL) || !meth->is_static()), "find_instance_method should have skipped statics");
    5.35    return meth;
    5.36  }
    5.37  
    5.38 @@ -1496,22 +1501,51 @@
    5.39      return InstanceKlass::find_instance_method(methods(), name, signature);
    5.40  }
    5.41  
    5.42 +// Find looks up the name/signature in the local methods array
    5.43 +// and filters on the overpass, static and private flags
    5.44 +// This returns the first one found
    5.45 +// note that the local methods array can have up to one overpass, one static
    5.46 +// and one instance (private or not) with the same name/signature
    5.47 +Method* InstanceKlass::find_local_method(Symbol* name, Symbol* signature,
    5.48 +                                        OverpassLookupMode overpass_mode,
    5.49 +                                        StaticLookupMode static_mode,
    5.50 +                                        PrivateLookupMode private_mode) const {
    5.51 +  return InstanceKlass::find_method_impl(methods(), name, signature, overpass_mode, static_mode, private_mode);
    5.52 +}
    5.53 +
    5.54 +// Find looks up the name/signature in the local methods array
    5.55 +// and filters on the overpass, static and private flags
    5.56 +// This returns the first one found
    5.57 +// note that the local methods array can have up to one overpass, one static
    5.58 +// and one instance (private or not) with the same name/signature
    5.59 +Method* InstanceKlass::find_local_method(Array<Method*>* methods,
    5.60 +                                        Symbol* name, Symbol* signature,
    5.61 +                                        OverpassLookupMode overpass_mode,
    5.62 +                                        StaticLookupMode static_mode,
    5.63 +                                        PrivateLookupMode private_mode) {
    5.64 +  return InstanceKlass::find_method_impl(methods, name, signature, overpass_mode, static_mode, private_mode);
    5.65 +}
    5.66 +
    5.67 +
    5.68  // find_method looks up the name/signature in the local methods array
    5.69  Method* InstanceKlass::find_method(
    5.70      Array<Method*>* methods, Symbol* name, Symbol* signature) {
    5.71 -  return InstanceKlass::find_method_impl(methods, name, signature, false, false);
    5.72 +  return InstanceKlass::find_method_impl(methods, name, signature, find_overpass, find_static, find_private);
    5.73  }
    5.74  
    5.75  Method* InstanceKlass::find_method_impl(
    5.76 -    Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass, bool skipping_static) {
    5.77 -  int hit = find_method_index(methods, name, signature, skipping_overpass, skipping_static);
    5.78 +    Array<Method*>* methods, Symbol* name, Symbol* signature,
    5.79 +    OverpassLookupMode overpass_mode, StaticLookupMode static_mode,
    5.80 +    PrivateLookupMode private_mode) {
    5.81 +  int hit = find_method_index(methods, name, signature, overpass_mode, static_mode, private_mode);
    5.82    return hit >= 0 ? methods->at(hit): NULL;
    5.83  }
    5.84  
    5.85 -bool InstanceKlass::method_matches(Method* m, Symbol* signature, bool skipping_overpass, bool skipping_static) {
    5.86 -    return (m->signature() == signature) &&
    5.87 +bool InstanceKlass::method_matches(Method* m, Symbol* signature, bool skipping_overpass, bool skipping_static, bool skipping_private) {
    5.88 +    return  ((m->signature() == signature) &&
    5.89              (!skipping_overpass || !m->is_overpass()) &&
    5.90 -            (!skipping_static || !m->is_static());
    5.91 +            (!skipping_static || !m->is_static()) &&
    5.92 +            (!skipping_private || !m->is_private()));
    5.93  }
    5.94  
    5.95  // Used directly for default_methods to find the index into the
    5.96 @@ -1521,15 +1555,25 @@
    5.97  // the search continues to find a potential non-overpass match.  This capability
    5.98  // is important during method resolution to prefer a static method, for example,
    5.99  // over an overpass method.
   5.100 +// There is the possibility in any _method's array to have the same name/signature
   5.101 +// for a static method, an overpass method and a local instance method
   5.102 +// To correctly catch a given method, the search criteria may need
   5.103 +// to explicitly skip the other two. For local instance methods, it
   5.104 +// is often necessary to skip private methods
   5.105  int InstanceKlass::find_method_index(
   5.106 -    Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass, bool skipping_static) {
   5.107 +    Array<Method*>* methods, Symbol* name, Symbol* signature,
   5.108 +    OverpassLookupMode overpass_mode, StaticLookupMode static_mode,
   5.109 +    PrivateLookupMode private_mode) {
   5.110 +  bool skipping_overpass = (overpass_mode == skip_overpass);
   5.111 +  bool skipping_static = (static_mode == skip_static);
   5.112 +  bool skipping_private = (private_mode == skip_private);
   5.113    int hit = binary_search(methods, name);
   5.114    if (hit != -1) {
   5.115      Method* m = methods->at(hit);
   5.116  
   5.117      // Do linear search to find matching signature.  First, quick check
   5.118      // for common case, ignoring overpasses if requested.
   5.119 -    if (method_matches(m, signature, skipping_overpass, skipping_static)) return hit;
   5.120 +    if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) return hit;
   5.121  
   5.122      // search downwards through overloaded methods
   5.123      int i;
   5.124 @@ -1537,18 +1581,18 @@
   5.125          Method* m = methods->at(i);
   5.126          assert(m->is_method(), "must be method");
   5.127          if (m->name() != name) break;
   5.128 -        if (method_matches(m, signature, skipping_overpass, skipping_static)) return i;
   5.129 +        if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) return i;
   5.130      }
   5.131      // search upwards
   5.132      for (i = hit + 1; i < methods->length(); ++i) {
   5.133          Method* m = methods->at(i);
   5.134          assert(m->is_method(), "must be method");
   5.135          if (m->name() != name) break;
   5.136 -        if (method_matches(m, signature, skipping_overpass, skipping_static)) return i;
   5.137 +        if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) return i;
   5.138      }
   5.139      // not found
   5.140  #ifdef ASSERT
   5.141 -    int index = skipping_overpass || skipping_static ? -1 : linear_search(methods, name, signature);
   5.142 +    int index = (skipping_overpass || skipping_static || skipping_private) ? -1 : linear_search(methods, name, signature);
   5.143      assert(index == -1, err_msg("binary search should have found entry %d", index));
   5.144  #endif
   5.145    }
   5.146 @@ -1574,16 +1618,16 @@
   5.147  
   5.148  // uncached_lookup_method searches both the local class methods array and all
   5.149  // superclasses methods arrays, skipping any overpass methods in superclasses.
   5.150 -Method* InstanceKlass::uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const {
   5.151 -  MethodLookupMode lookup_mode = mode;
   5.152 +Method* InstanceKlass::uncached_lookup_method(Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode) const {
   5.153 +  OverpassLookupMode overpass_local_mode = overpass_mode;
   5.154    Klass* klass = const_cast<InstanceKlass*>(this);
   5.155    while (klass != NULL) {
   5.156 -    Method* method = InstanceKlass::cast(klass)->find_method_impl(name, signature, (lookup_mode == skip_overpass));
   5.157 +    Method* method = InstanceKlass::cast(klass)->find_method_impl(name, signature, overpass_local_mode, find_static, find_private);
   5.158      if (method != NULL) {
   5.159        return method;
   5.160      }
   5.161      klass = InstanceKlass::cast(klass)->super();
   5.162 -    lookup_mode = skip_overpass;   // Always ignore overpass methods in superclasses
   5.163 +    overpass_local_mode = skip_overpass;   // Always ignore overpass methods in superclasses
   5.164    }
   5.165    return NULL;
   5.166  }
   5.167 @@ -1613,7 +1657,7 @@
   5.168    }
   5.169    // Look up interfaces
   5.170    if (m == NULL) {
   5.171 -    m = lookup_method_in_all_interfaces(name, signature, normal);
   5.172 +    m = lookup_method_in_all_interfaces(name, signature, find_defaults);
   5.173    }
   5.174    return m;
   5.175  }
   5.176 @@ -1623,7 +1667,7 @@
   5.177  // They should only be found in the initial InterfaceMethodRef
   5.178  Method* InstanceKlass::lookup_method_in_all_interfaces(Symbol* name,
   5.179                                                         Symbol* signature,
   5.180 -                                                       MethodLookupMode mode) const {
   5.181 +                                                       DefaultsLookupMode defaults_mode) const {
   5.182    Array<Klass*>* all_ifs = transitive_interfaces();
   5.183    int num_ifs = all_ifs->length();
   5.184    InstanceKlass *ik = NULL;
   5.185 @@ -1631,7 +1675,7 @@
   5.186      ik = InstanceKlass::cast(all_ifs->at(i));
   5.187      Method* m = ik->lookup_method(name, signature);
   5.188      if (m != NULL && m->is_public() && !m->is_static() &&
   5.189 -        ((mode != skip_defaults) || !m->is_default_method())) {
   5.190 +        ((defaults_mode != skip_defaults) || !m->is_default_method())) {
   5.191        return m;
   5.192      }
   5.193    }
     6.1 --- a/src/share/vm/oops/instanceKlass.hpp	Fri Jan 20 16:22:39 2017 +0000
     6.2 +++ b/src/share/vm/oops/instanceKlass.hpp	Thu Feb 02 00:29:28 2017 +0000
     6.3 @@ -1,5 +1,5 @@
     6.4  /*
     6.5 - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
     6.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
     6.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     6.8   *
     6.9   * This code is free software; you can redistribute it and/or modify it
    6.10 @@ -527,18 +527,36 @@
    6.11    Method* find_instance_method(Symbol* name, Symbol* signature);
    6.12    static Method* find_instance_method(Array<Method*>* methods, Symbol* name, Symbol* signature);
    6.13  
    6.14 +  // find a local method (returns NULL if not found)
    6.15 +  Method* find_local_method(Symbol* name, Symbol* signature,
    6.16 +                           OverpassLookupMode overpass_mode,
    6.17 +                           StaticLookupMode static_mode,
    6.18 +                           PrivateLookupMode private_mode) const;
    6.19 +
    6.20 +  // find a local method from given methods array (returns NULL if not found)
    6.21 +  static Method* find_local_method(Array<Method*>* methods,
    6.22 +                           Symbol* name, Symbol* signature,
    6.23 +                           OverpassLookupMode overpass_mode,
    6.24 +                           StaticLookupMode static_mode,
    6.25 +                           PrivateLookupMode private_mode);
    6.26 +
    6.27    // true if method matches signature and conforms to skipping_X conditions.
    6.28 -  static bool method_matches(Method* m, Symbol* signature, bool skipping_overpass, bool skipping_static);
    6.29 +  static bool method_matches(Method* m, Symbol* signature, bool skipping_overpass, bool skipping_static, bool skipping_private);
    6.30  
    6.31 -  // find a local method index in default_methods (returns -1 if not found)
    6.32 -  static int find_method_index(Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass, bool skipping_static);
    6.33 +  // find a local method index in methods or default_methods (returns -1 if not found)
    6.34 +  static int find_method_index(Array<Method*>* methods,
    6.35 +                               Symbol* name, Symbol* signature,
    6.36 +                               OverpassLookupMode overpass_mode,
    6.37 +                               StaticLookupMode static_mode,
    6.38 +                               PrivateLookupMode private_mode);
    6.39 +
    6.40  
    6.41    // lookup operation (returns NULL if not found)
    6.42 -  Method* uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const;
    6.43 +  Method* uncached_lookup_method(Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode) const;
    6.44  
    6.45    // lookup a method in all the interfaces that this class implements
    6.46    // (returns NULL if not found)
    6.47 -  Method* lookup_method_in_all_interfaces(Symbol* name, Symbol* signature, MethodLookupMode mode) const;
    6.48 +  Method* lookup_method_in_all_interfaces(Symbol* name, Symbol* signature, DefaultsLookupMode defaults_mode) const;
    6.49  
    6.50    // lookup a method in local defaults then in all interfaces
    6.51    // (returns NULL if not found)
    6.52 @@ -1089,8 +1107,15 @@
    6.53    Klass* array_klass_impl(bool or_null, TRAPS);
    6.54  
    6.55    // find a local method (returns NULL if not found)
    6.56 -  Method* find_method_impl(Symbol* name, Symbol* signature, bool skipping_overpass) const;
    6.57 -  static Method* find_method_impl(Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass, bool skipping_static);
    6.58 +  Method* find_method_impl(Symbol* name, Symbol* signature,
    6.59 +                           OverpassLookupMode overpass_mode,
    6.60 +                           StaticLookupMode static_mode,
    6.61 +                           PrivateLookupMode private_mode) const;
    6.62 +  static Method* find_method_impl(Array<Method*>* methods,
    6.63 +                                  Symbol* name, Symbol* signature,
    6.64 +                                  OverpassLookupMode overpass_mode,
    6.65 +                                  StaticLookupMode static_mode,
    6.66 +                                  PrivateLookupMode private_mode);
    6.67  
    6.68    // Free CHeap allocated fields.
    6.69    void release_C_heap_structures();
     7.1 --- a/src/share/vm/oops/klass.cpp	Fri Jan 20 16:22:39 2017 +0000
     7.2 +++ b/src/share/vm/oops/klass.cpp	Thu Feb 02 00:29:28 2017 +0000
     7.3 @@ -1,5 +1,5 @@
     7.4  /*
     7.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
     7.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
     7.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     7.8   *
     7.9   * This code is free software; you can redistribute it and/or modify it
    7.10 @@ -140,7 +140,7 @@
    7.11    return NULL;
    7.12  }
    7.13  
    7.14 -Method* Klass::uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const {
    7.15 +Method* Klass::uncached_lookup_method(Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode) const {
    7.16  #ifdef ASSERT
    7.17    tty->print_cr("Error: uncached_lookup_method called on a klass oop."
    7.18                  " Likely error: reflection method does not correctly"
     8.1 --- a/src/share/vm/oops/klass.hpp	Fri Jan 20 16:22:39 2017 +0000
     8.2 +++ b/src/share/vm/oops/klass.hpp	Thu Feb 02 00:29:28 2017 +0000
     8.3 @@ -1,5 +1,5 @@
     8.4  /*
     8.5 - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
     8.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
     8.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     8.8   *
     8.9   * This code is free software; you can redistribute it and/or modify it
    8.10 @@ -192,7 +192,10 @@
    8.11    void* operator new(size_t size, ClassLoaderData* loader_data, size_t word_size, TRAPS) throw();
    8.12  
    8.13   public:
    8.14 -  enum MethodLookupMode { normal, skip_overpass, skip_defaults };
    8.15 +  enum DefaultsLookupMode { find_defaults, skip_defaults };
    8.16 +  enum OverpassLookupMode { find_overpass, skip_overpass };
    8.17 +  enum StaticLookupMode   { find_static,   skip_static };
    8.18 +  enum PrivateLookupMode  { find_private,  skip_private };
    8.19  
    8.20    bool is_klass() const volatile { return true; }
    8.21  
    8.22 @@ -458,10 +461,10 @@
    8.23    // lookup operation for MethodLookupCache
    8.24    friend class MethodLookupCache;
    8.25    virtual Klass* find_field(Symbol* name, Symbol* signature, fieldDescriptor* fd) const;
    8.26 -  virtual Method* uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const;
    8.27 +  virtual Method* uncached_lookup_method(Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode) const;
    8.28   public:
    8.29    Method* lookup_method(Symbol* name, Symbol* signature) const {
    8.30 -    return uncached_lookup_method(name, signature, normal);
    8.31 +    return uncached_lookup_method(name, signature, find_overpass);
    8.32    }
    8.33  
    8.34    // array class with specific rank
     9.1 --- a/src/share/vm/oops/klassVtable.cpp	Fri Jan 20 16:22:39 2017 +0000
     9.2 +++ b/src/share/vm/oops/klassVtable.cpp	Thu Feb 02 00:29:28 2017 +0000
     9.3 @@ -1,5 +1,5 @@
     9.4  /*
     9.5 - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
     9.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
     9.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     9.8   *
     9.9   * This code is free software; you can redistribute it and/or modify it
    9.10 @@ -696,7 +696,7 @@
    9.11    // this check for all access permissions.
    9.12    InstanceKlass *sk = InstanceKlass::cast(super);
    9.13    if (sk->has_miranda_methods()) {
    9.14 -    if (sk->lookup_method_in_all_interfaces(name, signature, Klass::normal) != NULL) {
    9.15 +    if (sk->lookup_method_in_all_interfaces(name, signature, Klass::find_defaults) != NULL) {
    9.16        return false;  // found a matching miranda; we do not need a new entry
    9.17      }
    9.18    }
    9.19 @@ -729,7 +729,6 @@
    9.20    if (mhk->is_interface()) {
    9.21      assert(m->is_public(), "should be public");
    9.22      assert(ik()->implements_interface(method_holder) , "this class should implement the interface");
    9.23 -    // the search could find a miranda or a default method
    9.24      if (is_miranda(m, ik()->methods(), ik()->default_methods(), ik()->super())) {
    9.25        return true;
    9.26      }
    9.27 @@ -737,25 +736,57 @@
    9.28    return false;
    9.29  }
    9.30  
    9.31 -// check if a method is a miranda method, given a class's methods table,
    9.32 -// its default_method table  and its super
    9.33 -// Miranda methods are calculated twice:
    9.34 -// first: before vtable size calculation: including abstract and superinterface default
    9.35 +// Check if a method is a miranda method, given a class's methods array,
    9.36 +// its default_method table and its super class.
    9.37 +// "Miranda" means an abstract non-private method that would not be
    9.38 +// overridden for the local class.
    9.39 +// A "miranda" method should only include non-private interface
    9.40 +// instance methods, i.e. not private methods, not static methods,
    9.41 +// not default methods (concrete interface methods), not overpass methods.
    9.42 +// If a given class already has a local (including overpass) method, a
    9.43 +// default method, or any of its superclasses has the same which would have
    9.44 +// overridden an abstract method, then this is not a miranda method.
    9.45 +//
    9.46 +// Miranda methods are checked multiple times.
    9.47 +// Pass 1: during class load/class file parsing: before vtable size calculation:
    9.48 +// include superinterface abstract and default methods (non-private instance).
    9.49  // We include potential default methods to give them space in the vtable.
    9.50 -// During the first run, the default_methods list is empty
    9.51 -// This is seen by default method creation
    9.52 -// Second: recalculated during vtable initialization: only include abstract methods.
    9.53 +// During the first run, the current instanceKlass has not yet been
    9.54 +// created, the superclasses and superinterfaces do have instanceKlasses
    9.55 +// but may not have vtables, the default_methods list is empty, no overpasses.
    9.56 +// This is seen by default method creation.
    9.57 +//
    9.58 +// Pass 2: recalculated during vtable initialization: only include abstract methods.
    9.59 +// The goal of pass 2 is to walk through the superinterfaces to see if any of
    9.60 +// the superinterface methods (which were all abstract pre-default methods)
    9.61 +// need to be added to the vtable.
    9.62 +// With the addition of default methods, we have three new challenges:
    9.63 +// overpasses, static interface methods and private interface methods.
    9.64 +// Static and private interface methods do not get added to the vtable and
    9.65 +// are not seen by the method resolution process, so we skip those.
    9.66 +// Overpass methods are already in the vtable, so vtable lookup will
    9.67 +// find them and we don't need to add a miranda method to the end of
    9.68 +// the vtable. So we look for overpass methods and if they are found we
    9.69 +// return false. Note that we inherit our superclasses vtable, so
    9.70 +// the superclass' search also needs to use find_overpass so that if
    9.71 +// one is found we return false.
    9.72 +// False means - we don't need a miranda method added to the vtable.
    9.73 +//
    9.74  // During the second run, default_methods is set up, so concrete methods from
    9.75  // superinterfaces with matching names/signatures to default_methods are already
    9.76  // in the default_methods list and do not need to be appended to the vtable
    9.77 -// as mirandas
    9.78 -// This is seen by link resolution and selection.
    9.79 -// "miranda" means not static, not defined by this class.
    9.80 -// private methods in interfaces do not belong in the miranda list.
    9.81 -// the caller must make sure that the method belongs to an interface implemented by the class
    9.82 -// Miranda methods only include public interface instance methods
    9.83 -// Not private methods, not static methods, not default == concrete abstract
    9.84 -// Miranda methods also do not include overpass methods in interfaces
    9.85 +// as mirandas. Abstract methods may already have been handled via
    9.86 +// overpasses - either local or superclass overpasses, which may be
    9.87 +// in the vtable already.
    9.88 +//
    9.89 +// Pass 3: They are also checked by link resolution and selection,
    9.90 +// for invocation on a method (not interface method) reference that
    9.91 +// resolves to a method with an interface as its method_holder.
    9.92 +// Used as part of walking from the bottom of the vtable to find
    9.93 +// the vtable index for the miranda method.
    9.94 +//
    9.95 +// Part of the Miranda Rights in the US mean that if you do not have
    9.96 +// an attorney one will be appointed for you.
    9.97  bool klassVtable::is_miranda(Method* m, Array<Method*>* class_methods,
    9.98                               Array<Method*>* default_methods, Klass* super) {
    9.99    if (m->is_static() || m->is_private() || m->is_overpass()) {
   9.100 @@ -763,44 +794,36 @@
   9.101    }
   9.102    Symbol* name = m->name();
   9.103    Symbol* signature = m->signature();
   9.104 -  Method* mo;
   9.105  
   9.106 -  if ((mo = InstanceKlass::find_instance_method(class_methods, name, signature)) == NULL) {
   9.107 -    // did not find it in the method table of the current class
   9.108 -    if ((default_methods == NULL) ||
   9.109 -        InstanceKlass::find_method(default_methods, name, signature) == NULL) {
   9.110 -      if (super == NULL) {
   9.111 -        // super doesn't exist
   9.112 -        return true;
   9.113 -      }
   9.114 -
   9.115 -      mo = InstanceKlass::cast(super)->lookup_method(name, signature);
   9.116 -      while (mo != NULL && mo->access_flags().is_static()
   9.117 -             && mo->method_holder() != NULL
   9.118 -             && mo->method_holder()->super() != NULL)
   9.119 -      {
   9.120 -         mo = mo->method_holder()->super()->uncached_lookup_method(name, signature, Klass::normal);
   9.121 -      }
   9.122 -      if (mo == NULL || mo->access_flags().is_private() ) {
   9.123 -        // super class hierarchy does not implement it or protection is different
   9.124 -        return true;
   9.125 -      }
   9.126 -    }
   9.127 -  } else {
   9.128 -     // if the local class has a private method, the miranda will not
   9.129 -     // override it, so a vtable slot is needed
   9.130 -     if (mo->access_flags().is_private()) {
   9.131 -
   9.132 -       // Second round, weed out any superinterface methods that turned
   9.133 -       // into default methods, i.e. were concrete not abstract in the end
   9.134 -       if ((default_methods == NULL) ||
   9.135 -         InstanceKlass::find_method(default_methods, name, signature) == NULL) {
   9.136 -         return true;
   9.137 -       }
   9.138 -    }
   9.139 +  // First look in local methods to see if already covered
   9.140 +  if (InstanceKlass::find_local_method(class_methods, name, signature,
   9.141 +              Klass::find_overpass, Klass::skip_static, Klass::skip_private) != NULL)
   9.142 +  {
   9.143 +    return false;
   9.144    }
   9.145  
   9.146 -  return false;
   9.147 +  // Check local default methods
   9.148 +  if ((default_methods != NULL) &&
   9.149 +    (InstanceKlass::find_method(default_methods, name, signature) != NULL))
   9.150 +   {
   9.151 +     return false;
   9.152 +   }
   9.153 +
   9.154 +  InstanceKlass* cursuper;
   9.155 +  // Iterate on all superclasses, which should have instanceKlasses
   9.156 +  // Note that we explicitly look for overpasses at each level.
   9.157 +  // Overpasses may or may not exist for supers for pass 1,
   9.158 +  // they should have been created for pass 2 and later.
   9.159 +
   9.160 +  for (cursuper = InstanceKlass::cast(super); cursuper != NULL;  cursuper = (InstanceKlass*)cursuper->super())
   9.161 +  {
   9.162 +     if (cursuper->find_local_method(name, signature,
   9.163 +           Klass::find_overpass, Klass::skip_static, Klass::skip_private) != NULL) {
   9.164 +       return false;
   9.165 +     }
   9.166 +  }
   9.167 +
   9.168 +  return true;
   9.169  }
   9.170  
   9.171  // Scans current_interface_methods for miranda methods that do not
   9.172 @@ -836,7 +859,7 @@
   9.173        if (is_miranda(im, class_methods, default_methods, super)) { // is it a miranda at all?
   9.174          InstanceKlass *sk = InstanceKlass::cast(super);
   9.175          // check if it is a duplicate of a super's miranda
   9.176 -        if (sk->lookup_method_in_all_interfaces(im->name(), im->signature(), Klass::normal) == NULL) {
   9.177 +        if (sk->lookup_method_in_all_interfaces(im->name(), im->signature(), Klass::find_defaults) == NULL) {
   9.178            new_mirandas->append(im);
   9.179          }
   9.180          if (all_mirandas != NULL) {
    10.1 --- a/src/share/vm/prims/jvm.cpp	Fri Jan 20 16:22:39 2017 +0000
    10.2 +++ b/src/share/vm/prims/jvm.cpp	Thu Feb 02 00:29:28 2017 +0000
    10.3 @@ -1,5 +1,5 @@
    10.4  /*
    10.5 - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
    10.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
    10.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    10.8   *
    10.9   * This code is free software; you can redistribute it and/or modify it
   10.10 @@ -1346,7 +1346,7 @@
   10.11    Method* m_oop = object->klass()->uncached_lookup_method(
   10.12                                             vmSymbols::run_method_name(),
   10.13                                             vmSymbols::void_object_signature(),
   10.14 -                                           Klass::normal);
   10.15 +                                           Klass::find_overpass);
   10.16    methodHandle m (THREAD, m_oop);
   10.17    if (m.is_null() || !m->is_method() || !m()->is_public() || m()->is_static()) {
   10.18      THROW_MSG_0(vmSymbols::java_lang_InternalError(), "No run method");
    11.1 --- a/src/share/vm/prims/nativeLookup.cpp	Fri Jan 20 16:22:39 2017 +0000
    11.2 +++ b/src/share/vm/prims/nativeLookup.cpp	Thu Feb 02 00:29:28 2017 +0000
    11.3 @@ -1,5 +1,5 @@
    11.4  /*
    11.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
    11.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
    11.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    11.8   *
    11.9   * This code is free software; you can redistribute it and/or modify it
   11.10 @@ -408,7 +408,7 @@
   11.11  
   11.12    // Find method and invoke standard lookup
   11.13    methodHandle method (THREAD,
   11.14 -                       klass->uncached_lookup_method(m_name, s_name, Klass::normal));
   11.15 +                       klass->uncached_lookup_method(m_name, s_name, Klass::find_overpass));
   11.16    address result = lookup(method, in_base_library, CATCH);
   11.17    assert(in_base_library, "must be in basic library");
   11.18    guarantee(result != NULL, "must be non NULL");
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/test/runtime/lambda-features/TestStaticandInstance.java	Thu Feb 02 00:29:28 2017 +0000
    12.3 @@ -0,0 +1,272 @@
    12.4 +/*
    12.5 + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
    12.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    12.7 + *
    12.8 + * This code is free software; you can redistribute it and/or modify it
    12.9 + * under the terms of the GNU General Public License version 2 only, as
   12.10 + * published by the Free Software Foundation.
   12.11 + *
   12.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   12.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   12.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   12.15 + * version 2 for more details (a copy is included in the LICENSE file that
   12.16 + * accompanied this code).
   12.17 + *
   12.18 + * You should have received a copy of the GNU General Public License version
   12.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   12.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   12.21 + *
   12.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   12.23 + * or visit www.oracle.com if you need additional information or have any
   12.24 + * questions.
   12.25 + *
   12.26 + */
   12.27 +
   12.28 +/*
   12.29 + * @test
   12.30 + * @bug 8087342
   12.31 + * @summary Test linkresolver search static, instance and overpass duplicates
   12.32 + * @run main/othervm -Xverify:none TestStaticandInstance
   12.33 + */
   12.34 +
   12.35 +
   12.36 +import java.util.*;
   12.37 +import jdk.internal.org.objectweb.asm.*;
   12.38 +import static jdk.internal.org.objectweb.asm.Opcodes.*;
   12.39 +
   12.40 +public class TestStaticandInstance {
   12.41 +  static final String stringC = "C";
   12.42 +  static final String stringD = "D";
   12.43 +  static final String stringI = "I";
   12.44 +
   12.45 +  public static void main(String args[]) throws Throwable {
   12.46 +    ClassLoader cl = new ClassLoader() {
   12.47 +      public Class<?> loadClass(String name) throws ClassNotFoundException {
   12.48 +        Class retClass;
   12.49 +        if ((retClass = findLoadedClass(name)) != null) {
   12.50 +           return retClass;
   12.51 +        }
   12.52 +        if (stringC.equals(name)) {
   12.53 +            byte[] classFile=dumpC();
   12.54 +            return defineClass(stringC, classFile, 0, classFile.length);
   12.55 +        }
   12.56 +        if (stringD.equals(name)) {
   12.57 +            byte[] classFile=dumpD();
   12.58 +            return defineClass(stringD, classFile, 0, classFile.length);
   12.59 +        }
   12.60 +        if (stringI.equals(name)) {
   12.61 +            byte[] classFile=dumpI();
   12.62 +            return defineClass(stringI, classFile, 0, classFile.length);
   12.63 +        }
   12.64 +        return super.loadClass(name);
   12.65 +      }
   12.66 +    };
   12.67 +
   12.68 +    Class classC = cl.loadClass(stringC);
   12.69 +    Class classI = cl.loadClass(stringI);
   12.70 +
   12.71 +    try {
   12.72 +      int staticret = (Integer)cl.loadClass(stringD).getDeclaredMethod("CallStatic").invoke(null);
   12.73 +      if (staticret != 1) {
   12.74 +        throw new RuntimeException("invokestatic failed to call correct method");
   12.75 +      }
   12.76 +      System.out.println("staticret: " + staticret); // should be 1
   12.77 +
   12.78 +      int invokeinterfaceret = (Integer)cl.loadClass(stringD).getDeclaredMethod("CallInterface").invoke(null);
   12.79 +      if (invokeinterfaceret != 0) {
   12.80 +        throw new RuntimeException(String.format("Expected java.lang.AbstractMethodError, got %d", invokeinterfaceret));
   12.81 +      }
   12.82 +      System.out.println("invokeinterfaceret: AbstractMethodError");
   12.83 +
   12.84 +      int invokevirtualret = (Integer)cl.loadClass(stringD).getDeclaredMethod("CallVirtual").invoke(null);
   12.85 +      if (invokevirtualret != 0) {
   12.86 +        throw new RuntimeException(String.format("Expected java.lang.IncompatibleClassChangeError, got %d", invokevirtualret));
   12.87 +      }
   12.88 +      System.out.println("invokevirtualret: IncompatibleClassChangeError");
   12.89 +    } catch (java.lang.Throwable e) {
   12.90 +      throw new RuntimeException("Unexpected exception: " + e.getMessage());
   12.91 +    }
   12.92 +  }
   12.93 +
   12.94 +/*
   12.95 +interface I {
   12.96 +  public int m(); // abstract
   12.97 +  default int q() { return 3; } // trigger defmeth processing: C gets AME overpass
   12.98 +}
   12.99 +
  12.100 +// C gets static, private and AME overpass m()I with -Xverify:none
  12.101 +class C implements I {
  12.102 +  static int m() { return 1;}  // javac with "n()" and patch to "m()"
  12.103 +  private int m() { return 2;} // javac with public and patch to private
  12.104 +}
  12.105 +
  12.106 +public class D {
  12.107 +  public static int CallStatic() {
  12.108 +    int staticret = C.m();    // javac with "C.n" and patch to "C.m"
  12.109 +    return staticret;
  12.110 +  }
  12.111 +  public static int CallInterface() throws AbstractMethodError{
  12.112 +    try {
  12.113 +      I myI = new C();
  12.114 +      return myI.m();
  12.115 +    } catch (java.lang.AbstractMethodError e) {
  12.116 +      return 0; // for success
  12.117 +    }
  12.118 +  }
  12.119 +  public static int CallVirtual() {
  12.120 +    try {
  12.121 +      C myC = new C();
  12.122 +      return myC.m();
  12.123 +    } catch (java.lang.IncompatibleClassChangeError e) {
  12.124 +      return 0; // for success
  12.125 +    }
  12.126 +  }
  12.127 +}
  12.128 +*/
  12.129 +
  12.130 +  public static byte[] dumpC() {
  12.131 +
  12.132 +    ClassWriter cw = new ClassWriter(0);
  12.133 +    FieldVisitor fv;
  12.134 +    MethodVisitor mv;
  12.135 +    AnnotationVisitor av0;
  12.136 +
  12.137 +    cw.visit(52, ACC_SUPER, "C", null, "java/lang/Object", new String[] { "I" });
  12.138 +
  12.139 +    {
  12.140 +      mv = cw.visitMethod(0, "<init>", "()V", null, null);
  12.141 +      mv.visitCode();
  12.142 +      mv.visitVarInsn(ALOAD, 0);
  12.143 +      mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
  12.144 +      mv.visitInsn(RETURN);
  12.145 +      mv.visitMaxs(1, 1);
  12.146 +      mv.visitEnd();
  12.147 +    }
  12.148 +    {
  12.149 +      mv = cw.visitMethod(ACC_STATIC, "m", "()I", null, null);
  12.150 +      mv.visitCode();
  12.151 +      mv.visitInsn(ICONST_1);
  12.152 +      mv.visitInsn(IRETURN);
  12.153 +      mv.visitMaxs(1, 0);
  12.154 +      mv.visitEnd();
  12.155 +    }
  12.156 +    {
  12.157 +      mv = cw.visitMethod(ACC_PRIVATE, "m", "()I", null, null);
  12.158 +      mv.visitCode();
  12.159 +      mv.visitInsn(ICONST_2);
  12.160 +      mv.visitInsn(IRETURN);
  12.161 +      mv.visitMaxs(1, 1);
  12.162 +      mv.visitEnd();
  12.163 +    }
  12.164 +    cw.visitEnd();
  12.165 +
  12.166 +    return cw.toByteArray();
  12.167 +  }
  12.168 +
  12.169 +  public static byte[] dumpD () {
  12.170 +
  12.171 +    ClassWriter cw = new ClassWriter(0);
  12.172 +    FieldVisitor fv;
  12.173 +    MethodVisitor mv;
  12.174 +    AnnotationVisitor av0;
  12.175 +
  12.176 +    cw.visit(52, ACC_PUBLIC + ACC_SUPER, "D", null, "java/lang/Object", null);
  12.177 +
  12.178 +    {
  12.179 +      mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
  12.180 +      mv.visitCode();
  12.181 +      mv.visitVarInsn(ALOAD, 0);
  12.182 +      mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
  12.183 +      mv.visitInsn(RETURN);
  12.184 +      mv.visitMaxs(1, 1);
  12.185 +      mv.visitEnd();
  12.186 +    }
  12.187 +    {
  12.188 +      mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "CallStatic", "()I", null, null);
  12.189 +      mv.visitCode();
  12.190 +      mv.visitMethodInsn(INVOKESTATIC, "C", "m", "()I", false);
  12.191 +      mv.visitVarInsn(ISTORE, 0);
  12.192 +      mv.visitVarInsn(ILOAD, 0);
  12.193 +      mv.visitInsn(IRETURN);
  12.194 +      mv.visitMaxs(1, 1);
  12.195 +      mv.visitEnd();
  12.196 +    }
  12.197 +    {
  12.198 +      mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "CallInterface", "()I", null, new String[] { "java/lang/AbstractMethodError" });
  12.199 +      mv.visitCode();
  12.200 +      Label l0 = new Label();
  12.201 +      Label l1 = new Label();
  12.202 +      Label l2 = new Label();
  12.203 +      mv.visitTryCatchBlock(l0, l1, l2, "java/lang/AbstractMethodError");
  12.204 +      mv.visitLabel(l0);
  12.205 +      mv.visitTypeInsn(NEW, "C");
  12.206 +      mv.visitInsn(DUP);
  12.207 +      mv.visitMethodInsn(INVOKESPECIAL, "C", "<init>", "()V", false);
  12.208 +      mv.visitVarInsn(ASTORE, 0);
  12.209 +      mv.visitVarInsn(ALOAD, 0);
  12.210 +      mv.visitMethodInsn(INVOKEINTERFACE, "I", "m", "()I", true);
  12.211 +      mv.visitLabel(l1);
  12.212 +      mv.visitInsn(IRETURN);
  12.213 +      mv.visitLabel(l2);
  12.214 +      mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/AbstractMethodError"});
  12.215 +      mv.visitVarInsn(ASTORE, 0);
  12.216 +      mv.visitInsn(ICONST_0);
  12.217 +      mv.visitInsn(IRETURN);
  12.218 +      mv.visitMaxs(2, 1);
  12.219 +      mv.visitEnd();
  12.220 +    }
  12.221 +    {
  12.222 +      mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "CallVirtual", "()I", null, null);
  12.223 +      mv.visitCode();
  12.224 +      Label l0 = new Label();
  12.225 +      Label l1 = new Label();
  12.226 +      Label l2 = new Label();
  12.227 +      mv.visitTryCatchBlock(l0, l1, l2, "java/lang/IncompatibleClassChangeError");
  12.228 +      mv.visitLabel(l0);
  12.229 +      mv.visitTypeInsn(NEW, "C");
  12.230 +      mv.visitInsn(DUP);
  12.231 +      mv.visitMethodInsn(INVOKESPECIAL, "C", "<init>", "()V", false);
  12.232 +      mv.visitVarInsn(ASTORE, 0);
  12.233 +      mv.visitVarInsn(ALOAD, 0);
  12.234 +      mv.visitMethodInsn(INVOKEVIRTUAL, "C", "m", "()I", false);
  12.235 +      mv.visitLabel(l1);
  12.236 +      mv.visitInsn(IRETURN);
  12.237 +      mv.visitLabel(l2);
  12.238 +      mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"java/lang/IncompatibleClassChangeError"});
  12.239 +      mv.visitVarInsn(ASTORE, 0);
  12.240 +      mv.visitInsn(ICONST_0);
  12.241 +      mv.visitInsn(IRETURN);
  12.242 +      mv.visitMaxs(2, 1);
  12.243 +      mv.visitEnd();
  12.244 +    }
  12.245 +    cw.visitEnd();
  12.246 +
  12.247 +    return cw.toByteArray();
  12.248 +  }
  12.249 +
  12.250 +  public static byte[] dumpI() {
  12.251 +
  12.252 +    ClassWriter cw = new ClassWriter(0);
  12.253 +    FieldVisitor fv;
  12.254 +    MethodVisitor mv;
  12.255 +    AnnotationVisitor av0;
  12.256 +
  12.257 +    cw.visit(52, ACC_ABSTRACT + ACC_INTERFACE, "I", null, "java/lang/Object", null);
  12.258 +
  12.259 +    {
  12.260 +      mv = cw.visitMethod(ACC_PUBLIC + ACC_ABSTRACT, "m", "()I", null, null);
  12.261 +      mv.visitEnd();
  12.262 +    }
  12.263 +    {
  12.264 +      mv = cw.visitMethod(ACC_PUBLIC, "q", "()I", null, null);
  12.265 +      mv.visitCode();
  12.266 +      mv.visitInsn(ICONST_3);
  12.267 +      mv.visitInsn(IRETURN);
  12.268 +      mv.visitMaxs(1, 1);
  12.269 +      mv.visitEnd();
  12.270 +    }
  12.271 +    cw.visitEnd();
  12.272 +
  12.273 +    return cw.toByteArray();
  12.274 +  }
  12.275 +}

mercurial