src/share/vm/oops/instanceKlass.cpp

changeset 8716
619700f41f8e
parent 8640
d2e8a8cd4166
child 8721
575f637864df
     1.1 --- a/src/share/vm/oops/instanceKlass.cpp	Fri Jan 20 16:22:39 2017 +0000
     1.2 +++ b/src/share/vm/oops/instanceKlass.cpp	Thu Feb 02 00:29:28 2017 +0000
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 1997, 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 @@ -1475,18 +1475,23 @@
    1.11  
    1.12  // find_method looks up the name/signature in the local methods array
    1.13  Method* InstanceKlass::find_method(Symbol* name, Symbol* signature) const {
    1.14 -  return find_method_impl(name, signature, false);
    1.15 +  return find_method_impl(name, signature, find_overpass, find_static, find_private);
    1.16  }
    1.17  
    1.18 -Method* InstanceKlass::find_method_impl(Symbol* name, Symbol* signature, bool skipping_overpass) const {
    1.19 -  return InstanceKlass::find_method_impl(methods(), name, signature, skipping_overpass, false);
    1.20 +Method* InstanceKlass::find_method_impl(Symbol* name, Symbol* signature,
    1.21 +                                        OverpassLookupMode overpass_mode,
    1.22 +                                        StaticLookupMode static_mode,
    1.23 +                                        PrivateLookupMode private_mode) const {
    1.24 +  return InstanceKlass::find_method_impl(methods(), name, signature, overpass_mode, static_mode, private_mode);
    1.25  }
    1.26  
    1.27  // find_instance_method looks up the name/signature in the local methods array
    1.28  // and skips over static methods
    1.29  Method* InstanceKlass::find_instance_method(
    1.30      Array<Method*>* methods, Symbol* name, Symbol* signature) {
    1.31 -  Method* meth = InstanceKlass::find_method_impl(methods, name, signature, false, true);
    1.32 +  Method* meth = InstanceKlass::find_method_impl(methods, name, signature,
    1.33 +                                                 find_overpass, skip_static, find_private);
    1.34 +  assert(((meth == NULL) || !meth->is_static()), "find_instance_method should have skipped statics");
    1.35    return meth;
    1.36  }
    1.37  
    1.38 @@ -1496,22 +1501,51 @@
    1.39      return InstanceKlass::find_instance_method(methods(), name, signature);
    1.40  }
    1.41  
    1.42 +// Find looks up the name/signature in the local methods array
    1.43 +// and filters on the overpass, static and private flags
    1.44 +// This returns the first one found
    1.45 +// note that the local methods array can have up to one overpass, one static
    1.46 +// and one instance (private or not) with the same name/signature
    1.47 +Method* InstanceKlass::find_local_method(Symbol* name, Symbol* signature,
    1.48 +                                        OverpassLookupMode overpass_mode,
    1.49 +                                        StaticLookupMode static_mode,
    1.50 +                                        PrivateLookupMode private_mode) const {
    1.51 +  return InstanceKlass::find_method_impl(methods(), name, signature, overpass_mode, static_mode, private_mode);
    1.52 +}
    1.53 +
    1.54 +// Find looks up the name/signature in the local methods array
    1.55 +// and filters on the overpass, static and private flags
    1.56 +// This returns the first one found
    1.57 +// note that the local methods array can have up to one overpass, one static
    1.58 +// and one instance (private or not) with the same name/signature
    1.59 +Method* InstanceKlass::find_local_method(Array<Method*>* methods,
    1.60 +                                        Symbol* name, Symbol* signature,
    1.61 +                                        OverpassLookupMode overpass_mode,
    1.62 +                                        StaticLookupMode static_mode,
    1.63 +                                        PrivateLookupMode private_mode) {
    1.64 +  return InstanceKlass::find_method_impl(methods, name, signature, overpass_mode, static_mode, private_mode);
    1.65 +}
    1.66 +
    1.67 +
    1.68  // find_method looks up the name/signature in the local methods array
    1.69  Method* InstanceKlass::find_method(
    1.70      Array<Method*>* methods, Symbol* name, Symbol* signature) {
    1.71 -  return InstanceKlass::find_method_impl(methods, name, signature, false, false);
    1.72 +  return InstanceKlass::find_method_impl(methods, name, signature, find_overpass, find_static, find_private);
    1.73  }
    1.74  
    1.75  Method* InstanceKlass::find_method_impl(
    1.76 -    Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass, bool skipping_static) {
    1.77 -  int hit = find_method_index(methods, name, signature, skipping_overpass, skipping_static);
    1.78 +    Array<Method*>* methods, Symbol* name, Symbol* signature,
    1.79 +    OverpassLookupMode overpass_mode, StaticLookupMode static_mode,
    1.80 +    PrivateLookupMode private_mode) {
    1.81 +  int hit = find_method_index(methods, name, signature, overpass_mode, static_mode, private_mode);
    1.82    return hit >= 0 ? methods->at(hit): NULL;
    1.83  }
    1.84  
    1.85 -bool InstanceKlass::method_matches(Method* m, Symbol* signature, bool skipping_overpass, bool skipping_static) {
    1.86 -    return (m->signature() == signature) &&
    1.87 +bool InstanceKlass::method_matches(Method* m, Symbol* signature, bool skipping_overpass, bool skipping_static, bool skipping_private) {
    1.88 +    return  ((m->signature() == signature) &&
    1.89              (!skipping_overpass || !m->is_overpass()) &&
    1.90 -            (!skipping_static || !m->is_static());
    1.91 +            (!skipping_static || !m->is_static()) &&
    1.92 +            (!skipping_private || !m->is_private()));
    1.93  }
    1.94  
    1.95  // Used directly for default_methods to find the index into the
    1.96 @@ -1521,15 +1555,25 @@
    1.97  // the search continues to find a potential non-overpass match.  This capability
    1.98  // is important during method resolution to prefer a static method, for example,
    1.99  // over an overpass method.
   1.100 +// There is the possibility in any _method's array to have the same name/signature
   1.101 +// for a static method, an overpass method and a local instance method
   1.102 +// To correctly catch a given method, the search criteria may need
   1.103 +// to explicitly skip the other two. For local instance methods, it
   1.104 +// is often necessary to skip private methods
   1.105  int InstanceKlass::find_method_index(
   1.106 -    Array<Method*>* methods, Symbol* name, Symbol* signature, bool skipping_overpass, bool skipping_static) {
   1.107 +    Array<Method*>* methods, Symbol* name, Symbol* signature,
   1.108 +    OverpassLookupMode overpass_mode, StaticLookupMode static_mode,
   1.109 +    PrivateLookupMode private_mode) {
   1.110 +  bool skipping_overpass = (overpass_mode == skip_overpass);
   1.111 +  bool skipping_static = (static_mode == skip_static);
   1.112 +  bool skipping_private = (private_mode == skip_private);
   1.113    int hit = binary_search(methods, name);
   1.114    if (hit != -1) {
   1.115      Method* m = methods->at(hit);
   1.116  
   1.117      // Do linear search to find matching signature.  First, quick check
   1.118      // for common case, ignoring overpasses if requested.
   1.119 -    if (method_matches(m, signature, skipping_overpass, skipping_static)) return hit;
   1.120 +    if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) return hit;
   1.121  
   1.122      // search downwards through overloaded methods
   1.123      int i;
   1.124 @@ -1537,18 +1581,18 @@
   1.125          Method* m = methods->at(i);
   1.126          assert(m->is_method(), "must be method");
   1.127          if (m->name() != name) break;
   1.128 -        if (method_matches(m, signature, skipping_overpass, skipping_static)) return i;
   1.129 +        if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) return i;
   1.130      }
   1.131      // search upwards
   1.132      for (i = hit + 1; i < methods->length(); ++i) {
   1.133          Method* m = methods->at(i);
   1.134          assert(m->is_method(), "must be method");
   1.135          if (m->name() != name) break;
   1.136 -        if (method_matches(m, signature, skipping_overpass, skipping_static)) return i;
   1.137 +        if (method_matches(m, signature, skipping_overpass, skipping_static, skipping_private)) return i;
   1.138      }
   1.139      // not found
   1.140  #ifdef ASSERT
   1.141 -    int index = skipping_overpass || skipping_static ? -1 : linear_search(methods, name, signature);
   1.142 +    int index = (skipping_overpass || skipping_static || skipping_private) ? -1 : linear_search(methods, name, signature);
   1.143      assert(index == -1, err_msg("binary search should have found entry %d", index));
   1.144  #endif
   1.145    }
   1.146 @@ -1574,16 +1618,16 @@
   1.147  
   1.148  // uncached_lookup_method searches both the local class methods array and all
   1.149  // superclasses methods arrays, skipping any overpass methods in superclasses.
   1.150 -Method* InstanceKlass::uncached_lookup_method(Symbol* name, Symbol* signature, MethodLookupMode mode) const {
   1.151 -  MethodLookupMode lookup_mode = mode;
   1.152 +Method* InstanceKlass::uncached_lookup_method(Symbol* name, Symbol* signature, OverpassLookupMode overpass_mode) const {
   1.153 +  OverpassLookupMode overpass_local_mode = overpass_mode;
   1.154    Klass* klass = const_cast<InstanceKlass*>(this);
   1.155    while (klass != NULL) {
   1.156 -    Method* method = InstanceKlass::cast(klass)->find_method_impl(name, signature, (lookup_mode == skip_overpass));
   1.157 +    Method* method = InstanceKlass::cast(klass)->find_method_impl(name, signature, overpass_local_mode, find_static, find_private);
   1.158      if (method != NULL) {
   1.159        return method;
   1.160      }
   1.161      klass = InstanceKlass::cast(klass)->super();
   1.162 -    lookup_mode = skip_overpass;   // Always ignore overpass methods in superclasses
   1.163 +    overpass_local_mode = skip_overpass;   // Always ignore overpass methods in superclasses
   1.164    }
   1.165    return NULL;
   1.166  }
   1.167 @@ -1613,7 +1657,7 @@
   1.168    }
   1.169    // Look up interfaces
   1.170    if (m == NULL) {
   1.171 -    m = lookup_method_in_all_interfaces(name, signature, normal);
   1.172 +    m = lookup_method_in_all_interfaces(name, signature, find_defaults);
   1.173    }
   1.174    return m;
   1.175  }
   1.176 @@ -1623,7 +1667,7 @@
   1.177  // They should only be found in the initial InterfaceMethodRef
   1.178  Method* InstanceKlass::lookup_method_in_all_interfaces(Symbol* name,
   1.179                                                         Symbol* signature,
   1.180 -                                                       MethodLookupMode mode) const {
   1.181 +                                                       DefaultsLookupMode defaults_mode) const {
   1.182    Array<Klass*>* all_ifs = transitive_interfaces();
   1.183    int num_ifs = all_ifs->length();
   1.184    InstanceKlass *ik = NULL;
   1.185 @@ -1631,7 +1675,7 @@
   1.186      ik = InstanceKlass::cast(all_ifs->at(i));
   1.187      Method* m = ik->lookup_method(name, signature);
   1.188      if (m != NULL && m->is_public() && !m->is_static() &&
   1.189 -        ((mode != skip_defaults) || !m->is_default_method())) {
   1.190 +        ((defaults_mode != skip_defaults) || !m->is_default_method())) {
   1.191        return m;
   1.192      }
   1.193    }

mercurial