Mercurial > hg > truffle
comparison src/share/vm/classfile/defaultMethods.cpp @ 13055:fce21ac5968d
8027229: ICCE expected for >=2 maximally specific default methods.
Summary: Need to process defaults for interfaces for invokespecial
Reviewed-by: lfoltan, hseigel, coleenp, jrose
author | acorn |
---|---|
date | Wed, 13 Nov 2013 07:31:26 -0800 |
parents | fdd464c8d62e |
children | 096c224171c4 379f11bc04fc |
comparison
equal
deleted
inserted
replaced
13054:19f8a5d7600b | 13055:fce21ac5968d |
---|---|
169 _cancelled = false; | 169 _cancelled = false; |
170 _path.clear(); | 170 _path.clear(); |
171 } | 171 } |
172 bool is_cancelled() const { return _cancelled; } | 172 bool is_cancelled() const { return _cancelled; } |
173 | 173 |
174 // This code used to skip interface classes because their only | |
175 // superclass was j.l.Object which would be also covered by class | |
176 // superclass hierarchy walks. Now that the starting point can be | |
177 // an interface, we must ensure we catch j.l.Object as the super. | |
174 static bool has_super(InstanceKlass* cls) { | 178 static bool has_super(InstanceKlass* cls) { |
175 return cls->super() != NULL && !cls->is_interface(); | 179 return cls->super() != NULL; |
176 } | 180 } |
177 | 181 |
178 Node* node_at_depth(int i) const { | 182 Node* node_at_depth(int i) const { |
179 return (i >= _path.length()) ? NULL : _path.at(_path.length() - i - 1); | 183 return (i >= _path.length()) ? NULL : _path.at(_path.length() - i - 1); |
180 } | 184 } |
389 void determine_target(InstanceKlass* root, TRAPS) { | 393 void determine_target(InstanceKlass* root, TRAPS) { |
390 if (has_target() || throws_exception()) { | 394 if (has_target() || throws_exception()) { |
391 return; | 395 return; |
392 } | 396 } |
393 | 397 |
398 // Qualified methods are maximally-specific methods | |
399 // These include public, instance concrete (=default) and abstract methods | |
394 GrowableArray<Method*> qualified_methods; | 400 GrowableArray<Method*> qualified_methods; |
395 int num_defaults = 0; | 401 int num_defaults = 0; |
396 int default_index = -1; | 402 int default_index = -1; |
403 int qualified_index = -1; | |
397 for (int i = 0; i < _members.length(); ++i) { | 404 for (int i = 0; i < _members.length(); ++i) { |
398 Pair<Method*,QualifiedState> entry = _members.at(i); | 405 Pair<Method*,QualifiedState> entry = _members.at(i); |
399 if (entry.second == QUALIFIED) { | 406 if (entry.second == QUALIFIED) { |
400 qualified_methods.append(entry.first); | 407 qualified_methods.append(entry.first); |
401 default_index++; | 408 qualified_index++; |
402 if (entry.first->is_default_method()) { | 409 if (entry.first->is_default_method()) { |
403 num_defaults++; | 410 num_defaults++; |
411 default_index = qualified_index; | |
412 | |
404 } | 413 } |
405 } | 414 } |
406 } | 415 } |
407 | 416 |
408 if (qualified_methods.length() == 0) { | 417 if (qualified_methods.length() == 0) { |
409 _exception_message = generate_no_defaults_message(CHECK); | 418 _exception_message = generate_no_defaults_message(CHECK); |
410 _exception_name = vmSymbols::java_lang_AbstractMethodError(); | 419 _exception_name = vmSymbols::java_lang_AbstractMethodError(); |
411 } else if (qualified_methods.length() == 1) { | 420 // If only one qualified method is default, select that |
412 // leave abstract methods alone, they will be found via normal search path | |
413 Method* method = qualified_methods.at(0); | |
414 if (!method->is_abstract()) { | |
415 _selected_target = qualified_methods.at(0); | |
416 } | |
417 // If only one qualified method is default, select that | |
418 } else if (num_defaults == 1) { | 421 } else if (num_defaults == 1) { |
419 _selected_target = qualified_methods.at(default_index); | 422 _selected_target = qualified_methods.at(default_index); |
420 } else { | 423 } else if (num_defaults > 1) { |
421 _exception_message = generate_conflicts_message(&qualified_methods,CHECK); | 424 _exception_message = generate_conflicts_message(&qualified_methods,CHECK); |
422 _exception_name = vmSymbols::java_lang_IncompatibleClassChangeError(); | 425 _exception_name = vmSymbols::java_lang_IncompatibleClassChangeError(); |
423 if (TraceDefaultMethods) { | 426 if (TraceDefaultMethods) { |
424 _exception_message->print_value_on(tty); | 427 _exception_message->print_value_on(tty); |
425 tty->print_cr(""); | 428 tty->print_cr(""); |
426 } | 429 } |
427 } | 430 } |
431 // leave abstract methods alone, they will be found via normal search path | |
428 } | 432 } |
429 | 433 |
430 bool contains_signature(Symbol* query) { | 434 bool contains_signature(Symbol* query) { |
431 for (int i = 0; i < _members.length(); ++i) { | 435 for (int i = 0; i < _members.length(); ++i) { |
432 if (query == _members.at(i).first->signature()) { | 436 if (query == _members.at(i).first->signature()) { |
702 InstanceKlass* iklass = current_class(); | 706 InstanceKlass* iklass = current_class(); |
703 | 707 |
704 Method* m = iklass->find_method(_method_name, _method_signature); | 708 Method* m = iklass->find_method(_method_name, _method_signature); |
705 // private interface methods are not candidates for default methods | 709 // private interface methods are not candidates for default methods |
706 // invokespecial to private interface methods doesn't use default method logic | 710 // invokespecial to private interface methods doesn't use default method logic |
711 // The overpasses are your supertypes' errors, we do not include them | |
707 // future: take access controls into account for superclass methods | 712 // future: take access controls into account for superclass methods |
708 if (m != NULL && !m->is_static() && (!iklass->is_interface() || m->is_public())) { | 713 if (m != NULL && !m->is_static() && !m->is_overpass() && |
714 (!iklass->is_interface() || m->is_public())) { | |
709 if (_family == NULL) { | 715 if (_family == NULL) { |
710 _family = new StatefulMethodFamily(); | 716 _family = new StatefulMethodFamily(); |
711 } | 717 } |
712 | 718 |
713 if (iklass->is_interface()) { | 719 if (iklass->is_interface()) { |
779 loadKeepAlive.run(klass); | 785 loadKeepAlive.run(klass); |
780 | 786 |
781 #ifndef PRODUCT | 787 #ifndef PRODUCT |
782 if (TraceDefaultMethods) { | 788 if (TraceDefaultMethods) { |
783 ResourceMark rm; // be careful with these! | 789 ResourceMark rm; // be careful with these! |
784 tty->print_cr("Class %s requires default method processing", | 790 tty->print_cr("%s %s requires default method processing", |
791 klass->is_interface() ? "Interface" : "Class", | |
785 klass->name()->as_klass_external_name()); | 792 klass->name()->as_klass_external_name()); |
786 PrintHierarchy printer; | 793 PrintHierarchy printer; |
787 printer.run(klass); | 794 printer.run(klass); |
788 } | 795 } |
789 #endif // ndef PRODUCT | 796 #endif // ndef PRODUCT |
804 | 811 |
805 generate_erased_defaults(klass, empty_slots, slot, CHECK); | 812 generate_erased_defaults(klass, empty_slots, slot, CHECK); |
806 } | 813 } |
807 #ifndef PRODUCT | 814 #ifndef PRODUCT |
808 if (TraceDefaultMethods) { | 815 if (TraceDefaultMethods) { |
809 tty->print_cr("Creating overpasses..."); | 816 tty->print_cr("Creating defaults and overpasses..."); |
810 } | 817 } |
811 #endif // ndef PRODUCT | 818 #endif // ndef PRODUCT |
812 | 819 |
813 create_defaults_and_exceptions(empty_slots, klass, CHECK); | 820 create_defaults_and_exceptions(empty_slots, klass, CHECK); |
814 | 821 |
1074 // Replace klass methods with new merged lists | 1081 // Replace klass methods with new merged lists |
1075 klass->set_methods(merged_methods); | 1082 klass->set_methods(merged_methods); |
1076 klass->set_initial_method_idnum(new_size); | 1083 klass->set_initial_method_idnum(new_size); |
1077 | 1084 |
1078 ClassLoaderData* cld = klass->class_loader_data(); | 1085 ClassLoaderData* cld = klass->class_loader_data(); |
1079 MetadataFactory::free_array(cld, original_methods); | 1086 if (original_methods ->length() > 0) { |
1087 MetadataFactory::free_array(cld, original_methods); | |
1088 } | |
1080 if (original_ordering->length() > 0) { | 1089 if (original_ordering->length() > 0) { |
1081 klass->set_method_ordering(merged_ordering); | 1090 klass->set_method_ordering(merged_ordering); |
1082 MetadataFactory::free_array(cld, original_ordering); | 1091 MetadataFactory::free_array(cld, original_ordering); |
1083 } | 1092 } |
1084 } | 1093 } |