comparison src/share/vm/interpreter/linkResolver.cpp @ 17889:386dd1c71858

8033150: invokestatic: IncompatibleClassChangeError trying to invoke static method from a parent in presence of conflicting defaults. Summary: A static method should be preferred during method resolution over an overpass, search the current class as well as its superclasses. Reviewed-by: acorn, coleenp, kamg
author lfoltan
date Mon, 14 Apr 2014 14:27:45 -0400
parents a81bc2b2c4d3
children 78bbf4d43a14
comparison
equal deleted inserted replaced
17887:cd3c534f8f4a 17889:386dd1c71858
241 // According to JVM spec. $5.4.3c & $5.4.3d 241 // According to JVM spec. $5.4.3c & $5.4.3d
242 242
243 // Look up method in klasses, including static methods 243 // Look up method in klasses, including static methods
244 // Then look up local default methods 244 // Then look up local default methods
245 void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, bool in_imethod_resolve, TRAPS) { 245 void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, bool in_imethod_resolve, TRAPS) {
246 Method* result_oop = klass->uncached_lookup_method(name, signature); 246 // Ignore overpasses so statics can be found during resolution
247 Method* result_oop = klass->uncached_lookup_method(name, signature, Klass::skip_overpass);
247 248
248 // JDK 8, JVMS 5.4.3.4: Interface method resolution should 249 // JDK 8, JVMS 5.4.3.4: Interface method resolution should
249 // ignore static and non-public methods of java.lang.Object, 250 // ignore static and non-public methods of java.lang.Object,
250 // like clone, finalize, registerNatives. 251 // like clone, finalize, registerNatives.
251 if (in_imethod_resolve && 252 if (in_imethod_resolve &&
254 (result_oop->is_static() || !result_oop->is_public()) && 255 (result_oop->is_static() || !result_oop->is_public()) &&
255 result_oop->method_holder() == SystemDictionary::Object_klass()) { 256 result_oop->method_holder() == SystemDictionary::Object_klass()) {
256 result_oop = NULL; 257 result_oop = NULL;
257 } 258 }
258 259
260 // Before considering default methods, check for an overpass in the
261 // current class if a method has not been found.
262 if (result_oop == NULL) {
263 result_oop = InstanceKlass::cast(klass())->find_method(name, signature);
264 }
265
259 if (result_oop == NULL) { 266 if (result_oop == NULL) {
260 Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods(); 267 Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods();
261 if (default_methods != NULL) { 268 if (default_methods != NULL) {
262 result_oop = InstanceKlass::find_method(default_methods, name, signature); 269 result_oop = InstanceKlass::find_method(default_methods, name, signature);
263 } 270 }
274 } 281 }
275 282
276 // returns first instance method 283 // returns first instance method
277 // Looks up method in classes, then looks up local default methods 284 // Looks up method in classes, then looks up local default methods
278 void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { 285 void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
279 Method* result_oop = klass->uncached_lookup_method(name, signature); 286 Method* result_oop = klass->uncached_lookup_method(name, signature, Klass::normal);
280 result = methodHandle(THREAD, result_oop); 287 result = methodHandle(THREAD, result_oop);
281 while (!result.is_null() && result->is_static() && result->method_holder()->super() != NULL) { 288 while (!result.is_null() && result->is_static() && result->method_holder()->super() != NULL) {
282 KlassHandle super_klass = KlassHandle(THREAD, result->method_holder()->super()); 289 KlassHandle super_klass = KlassHandle(THREAD, result->method_holder()->super());
283 result = methodHandle(THREAD, super_klass->uncached_lookup_method(name, signature)); 290 result = methodHandle(THREAD, super_klass->uncached_lookup_method(name, signature, Klass::normal));
284 } 291 }
285 292
286 if (result.is_null()) { 293 if (result.is_null()) {
287 Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods(); 294 Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods();
288 if (default_methods != NULL) { 295 if (default_methods != NULL) {
300 Symbol* signature = resolved_method->signature(); 307 Symbol* signature = resolved_method->signature();
301 308
302 // First check in default method array 309 // First check in default method array
303 if (!resolved_method->is_abstract() && 310 if (!resolved_method->is_abstract() &&
304 (InstanceKlass::cast(klass())->default_methods() != NULL)) { 311 (InstanceKlass::cast(klass())->default_methods() != NULL)) {
305 int index = InstanceKlass::find_method_index(InstanceKlass::cast(klass())->default_methods(), name, signature); 312 int index = InstanceKlass::find_method_index(InstanceKlass::cast(klass())->default_methods(), name, signature, false);
306 if (index >= 0 ) { 313 if (index >= 0 ) {
307 vtable_index = InstanceKlass::cast(klass())->default_vtable_indices()->at(index); 314 vtable_index = InstanceKlass::cast(klass())->default_vtable_indices()->at(index);
308 } 315 }
309 } 316 }
310 if (vtable_index == Method::invalid_vtable_index) { 317 if (vtable_index == Method::invalid_vtable_index) {
320 InstanceKlass *ik = InstanceKlass::cast(klass()); 327 InstanceKlass *ik = InstanceKlass::cast(klass());
321 328
322 // Specify 'true' in order to skip default methods when searching the 329 // Specify 'true' in order to skip default methods when searching the
323 // interfaces. Function lookup_method_in_klasses() already looked for 330 // interfaces. Function lookup_method_in_klasses() already looked for
324 // the method in the default methods table. 331 // the method in the default methods table.
325 result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name, signature, true)); 332 result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name, signature, Klass::skip_defaults));
326 } 333 }
327 334
328 void LinkResolver::lookup_polymorphic_method(methodHandle& result, 335 void LinkResolver::lookup_polymorphic_method(methodHandle& result,
329 KlassHandle klass, Symbol* name, Symbol* full_signature, 336 KlassHandle klass, Symbol* name, Symbol* full_signature,
330 KlassHandle current_klass, 337 KlassHandle current_klass,