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 }