Mercurial > hg > graal-jvmci-8
comparison src/share/vm/classfile/defaultMethods.cpp @ 17488:c3f3cfd39184
8031059: invokestatic: ICCE trying to invoke static method when it clashes with an abstract method inherited from an interface
Summary: Do not create AME overpass if there is a matching static method
Reviewed-by: lfoltan, coleenp, kamg
author | hseigel |
---|---|
date | Fri, 10 Jan 2014 12:11:04 -0500 |
parents | 62e87648a4be |
children | d8041d695d19 386dd1c71858 |
comparison
equal
deleted
inserted
replaced
17487:9d39e8a8ff61 | 17488:c3f3cfd39184 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
388 | 388 |
389 Method* get_selected_target() { return _selected_target; } | 389 Method* get_selected_target() { return _selected_target; } |
390 Symbol* get_exception_message() { return _exception_message; } | 390 Symbol* get_exception_message() { return _exception_message; } |
391 Symbol* get_exception_name() { return _exception_name; } | 391 Symbol* get_exception_name() { return _exception_name; } |
392 | 392 |
393 // Return true if the specified klass has a static method that matches | |
394 // the name and signature of the target method. | |
395 bool has_matching_static(InstanceKlass* root) { | |
396 if (_members.length() > 0) { | |
397 Pair<Method*,QualifiedState> entry = _members.at(0); | |
398 Method* impl = root->find_method(entry.first->name(), | |
399 entry.first->signature()); | |
400 if ((impl != NULL) && impl->is_static()) { | |
401 return true; | |
402 } | |
403 } | |
404 return false; | |
405 } | |
406 | |
393 // Either sets the target or the exception error message | 407 // Either sets the target or the exception error message |
394 void determine_target(InstanceKlass* root, TRAPS) { | 408 void determine_target(InstanceKlass* root, TRAPS) { |
395 if (has_target() || throws_exception()) { | 409 if (has_target() || throws_exception()) { |
396 return; | 410 return; |
397 } | 411 } |
414 } | 428 } |
415 } | 429 } |
416 } | 430 } |
417 | 431 |
418 if (num_defaults == 0) { | 432 if (num_defaults == 0) { |
419 if (qualified_methods.length() == 0) { | 433 // If the root klass has a static method with matching name and signature |
420 _exception_message = generate_no_defaults_message(CHECK); | 434 // then do not generate an overpass method because it will hide the |
421 } else { | 435 // static method during resolution. |
422 assert(root != NULL, "Null root class"); | 436 if (!has_matching_static(root)) { |
423 _exception_message = generate_method_message(root->name(), qualified_methods.at(0), CHECK); | 437 if (qualified_methods.length() == 0) { |
424 } | 438 _exception_message = generate_no_defaults_message(CHECK); |
425 _exception_name = vmSymbols::java_lang_AbstractMethodError(); | 439 } else { |
440 assert(root != NULL, "Null root class"); | |
441 _exception_message = generate_method_message(root->name(), qualified_methods.at(0), CHECK); | |
442 } | |
443 _exception_name = vmSymbols::java_lang_AbstractMethodError(); | |
444 } | |
445 | |
426 // If only one qualified method is default, select that | 446 // If only one qualified method is default, select that |
427 } else if (num_defaults == 1) { | 447 } else if (num_defaults == 1) { |
428 _selected_target = qualified_methods.at(default_index); | 448 _selected_target = qualified_methods.at(default_index); |
429 } else if (num_defaults > 1) { | 449 |
430 _exception_message = generate_conflicts_message(&qualified_methods,CHECK); | 450 } else if (num_defaults > 1 && !has_matching_static(root)) { |
431 _exception_name = vmSymbols::java_lang_IncompatibleClassChangeError(); | 451 _exception_message = generate_conflicts_message(&qualified_methods,CHECK); |
452 _exception_name = vmSymbols::java_lang_IncompatibleClassChangeError(); | |
432 if (TraceDefaultMethods) { | 453 if (TraceDefaultMethods) { |
433 _exception_message->print_value_on(tty); | 454 _exception_message->print_value_on(tty); |
434 tty->print_cr(""); | 455 tty->print_cr(""); |
435 } | 456 } |
436 } | 457 } |