24 |
24 |
25 #include "precompiled.hpp" |
25 #include "precompiled.hpp" |
26 #include "classfile/bytecodeAssembler.hpp" |
26 #include "classfile/bytecodeAssembler.hpp" |
27 #include "classfile/defaultMethods.hpp" |
27 #include "classfile/defaultMethods.hpp" |
28 #include "classfile/symbolTable.hpp" |
28 #include "classfile/symbolTable.hpp" |
|
29 #include "logging/log.hpp" |
29 #include "memory/allocation.hpp" |
30 #include "memory/allocation.hpp" |
30 #include "memory/metadataFactory.hpp" |
31 #include "memory/metadataFactory.hpp" |
31 #include "memory/resourceArea.hpp" |
32 #include "memory/resourceArea.hpp" |
32 #include "runtime/signature.hpp" |
33 #include "runtime/signature.hpp" |
33 #include "runtime/thread.hpp" |
34 #include "runtime/thread.hpp" |
244 } |
243 } |
245 } while (!is_cancelled() && has_more_nodes()); |
244 } while (!is_cancelled() && has_more_nodes()); |
246 } |
245 } |
247 }; |
246 }; |
248 |
247 |
249 #ifndef PRODUCT |
|
250 class PrintHierarchy : public HierarchyVisitor<PrintHierarchy> { |
248 class PrintHierarchy : public HierarchyVisitor<PrintHierarchy> { |
|
249 private: |
|
250 outputStream* _st; |
251 public: |
251 public: |
252 |
|
253 bool visit() { |
252 bool visit() { |
254 InstanceKlass* cls = current_class(); |
253 InstanceKlass* cls = current_class(); |
255 streamIndentor si(tty, current_depth() * 2); |
254 streamIndentor si(_st, current_depth() * 2); |
256 tty->indent().print_cr("%s", cls->name()->as_C_string()); |
255 _st->indent().print_cr("%s", cls->name()->as_C_string()); |
257 return true; |
256 return true; |
258 } |
257 } |
259 |
258 |
260 void* new_node_data(InstanceKlass* cls) { return NULL; } |
259 void* new_node_data(InstanceKlass* cls) { return NULL; } |
261 void free_node_data(void* data) { return; } |
260 void free_node_data(void* data) { return; } |
|
261 |
|
262 PrintHierarchy(outputStream* st = tty) : _st(st) {} |
262 }; |
263 }; |
263 #endif // ndef PRODUCT |
|
264 |
264 |
265 // Used to register InstanceKlass objects and all related metadata structures |
265 // Used to register InstanceKlass objects and all related metadata structures |
266 // (Methods, ConstantPools) as "in-use" by the current thread so that they can't |
266 // (Methods, ConstantPools) as "in-use" by the current thread so that they can't |
267 // be deallocated by class redefinition while we're using them. The classes are |
267 // be deallocated by class redefinition while we're using them. The classes are |
268 // de-registered when this goes out of scope. |
268 // de-registered when this goes out of scope. |
432 _selected_target = qualified_methods.at(default_index); |
432 _selected_target = qualified_methods.at(default_index); |
433 |
433 |
434 } else if (num_defaults > 1) { |
434 } else if (num_defaults > 1) { |
435 _exception_message = generate_conflicts_message(&qualified_methods,CHECK); |
435 _exception_message = generate_conflicts_message(&qualified_methods,CHECK); |
436 _exception_name = vmSymbols::java_lang_IncompatibleClassChangeError(); |
436 _exception_name = vmSymbols::java_lang_IncompatibleClassChangeError(); |
437 if (TraceDefaultMethods) { |
437 if (log_is_enabled(Debug, defaultmethods)) { |
438 _exception_message->print_value_on(tty); |
438 ResourceMark rm; |
439 tty->cr(); |
439 outputStream* logstream = LogHandle(defaultmethods)::debug_stream(); |
|
440 _exception_message->print_value_on(logstream); |
|
441 logstream->cr(); |
440 } |
442 } |
441 } |
443 } |
442 } |
444 } |
443 |
445 |
444 bool contains_signature(Symbol* query) { |
446 bool contains_signature(Symbol* query) { |
446 if (query == _members.at(i).first->signature()) { |
448 if (query == _members.at(i).first->signature()) { |
447 return true; |
449 return true; |
448 } |
450 } |
449 } |
451 } |
450 return false; |
452 return false; |
451 } |
|
452 |
|
453 #ifndef PRODUCT |
|
454 void print_sig_on(outputStream* str, Symbol* signature, int indent) const { |
|
455 streamIndentor si(str, indent * 2); |
|
456 |
|
457 str->indent().print_cr("Logical Method %s:", signature->as_C_string()); |
|
458 |
|
459 streamIndentor si2(str); |
|
460 for (int i = 0; i < _members.length(); ++i) { |
|
461 str->indent(); |
|
462 print_method(str, _members.at(i).first); |
|
463 if (_members.at(i).second == DISQUALIFIED) { |
|
464 str->print(" (disqualified)"); |
|
465 } |
|
466 str->cr(); |
|
467 } |
|
468 |
|
469 if (_selected_target != NULL) { |
|
470 print_selected(str, 1); |
|
471 } |
|
472 } |
453 } |
473 |
454 |
474 void print_selected(outputStream* str, int indent) const { |
455 void print_selected(outputStream* str, int indent) const { |
475 assert(has_target(), "Should be called otherwise"); |
456 assert(has_target(), "Should be called otherwise"); |
476 streamIndentor si(str, indent * 2); |
457 streamIndentor si(str, indent * 2); |
477 str->indent().print("Selected method: "); |
458 str->indent().print("Selected method: "); |
478 print_method(str, _selected_target); |
459 print_method(str, _selected_target); |
479 Klass* method_holder = _selected_target->method_holder(); |
460 Klass* method_holder = _selected_target->method_holder(); |
480 if (!method_holder->is_interface()) { |
461 if (!method_holder->is_interface()) { |
481 tty->print(" : in superclass"); |
462 str->print(" : in superclass"); |
482 } |
463 } |
483 str->cr(); |
464 str->cr(); |
484 } |
465 } |
485 |
466 |
486 void print_exception(outputStream* str, int indent) { |
467 void print_exception(outputStream* str, int indent) { |
487 assert(throws_exception(), "Should be called otherwise"); |
468 assert(throws_exception(), "Should be called otherwise"); |
488 assert(_exception_name != NULL, "exception_name should be set"); |
469 assert(_exception_name != NULL, "exception_name should be set"); |
489 streamIndentor si(str, indent * 2); |
470 streamIndentor si(str, indent * 2); |
490 str->indent().print_cr("%s: %s", _exception_name->as_C_string(), _exception_message->as_C_string()); |
471 str->indent().print_cr("%s: %s", _exception_name->as_C_string(), _exception_message->as_C_string()); |
491 } |
472 } |
492 #endif // ndef PRODUCT |
|
493 }; |
473 }; |
494 |
474 |
495 Symbol* MethodFamily::generate_no_defaults_message(TRAPS) const { |
475 Symbol* MethodFamily::generate_no_defaults_message(TRAPS) const { |
496 return SymbolTable::new_symbol("No qualifying defaults found", THREAD); |
476 return SymbolTable::new_symbol("No qualifying defaults found", THREAD); |
497 } |
477 } |
606 |
586 |
607 void bind_family(MethodFamily* lm) { _binding = lm; } |
587 void bind_family(MethodFamily* lm) { _binding = lm; } |
608 bool is_bound() { return _binding != NULL; } |
588 bool is_bound() { return _binding != NULL; } |
609 MethodFamily* get_binding() { return _binding; } |
589 MethodFamily* get_binding() { return _binding; } |
610 |
590 |
611 #ifndef PRODUCT |
|
612 void print_on(outputStream* str) const { |
591 void print_on(outputStream* str) const { |
613 print_slot(str, name(), signature()); |
592 print_slot(str, name(), signature()); |
614 } |
593 } |
615 #endif // ndef PRODUCT |
|
616 }; |
594 }; |
617 |
595 |
618 static bool already_in_vtable_slots(GrowableArray<EmptyVtableSlot*>* slots, Method* m) { |
596 static bool already_in_vtable_slots(GrowableArray<EmptyVtableSlot*>* slots, Method* m) { |
619 bool found = false; |
597 bool found = false; |
620 for (int j = 0; j < slots->length(); ++j) { |
598 for (int j = 0; j < slots->length(); ++j) { |
679 } |
657 } |
680 } |
658 } |
681 super = super->java_super(); |
659 super = super->java_super(); |
682 } |
660 } |
683 |
661 |
684 #ifndef PRODUCT |
662 if (log_is_enabled(Debug, defaultmethods)) { |
685 if (TraceDefaultMethods) { |
663 log_debug(defaultmethods)("Slots that need filling:"); |
686 tty->print_cr("Slots that need filling:"); |
664 ResourceMark rm; |
687 streamIndentor si(tty); |
665 outputStream* logstream = LogHandle(defaultmethods)::debug_stream(); |
|
666 streamIndentor si(logstream); |
688 for (int i = 0; i < slots->length(); ++i) { |
667 for (int i = 0; i < slots->length(); ++i) { |
689 tty->indent(); |
668 logstream->indent(); |
690 slots->at(i)->print_on(tty); |
669 slots->at(i)->print_on(logstream); |
691 tty->cr(); |
670 logstream->cr(); |
692 } |
671 } |
693 } |
672 } |
694 #endif // ndef PRODUCT |
673 |
695 return slots; |
674 return slots; |
696 } |
675 } |
697 |
676 |
698 // Iterates over the superinterface type hierarchy looking for all methods |
677 // Iterates over the superinterface type hierarchy looking for all methods |
699 // with a specific erased signature. |
678 // with a specific erased signature. |
810 // Keep entire hierarchy alive for the duration of the computation |
789 // Keep entire hierarchy alive for the duration of the computation |
811 KeepAliveRegistrar keepAlive(THREAD); |
790 KeepAliveRegistrar keepAlive(THREAD); |
812 KeepAliveVisitor loadKeepAlive(&keepAlive); |
791 KeepAliveVisitor loadKeepAlive(&keepAlive); |
813 loadKeepAlive.run(klass); |
792 loadKeepAlive.run(klass); |
814 |
793 |
815 #ifndef PRODUCT |
794 if (log_is_enabled(Debug, defaultmethods)) { |
816 if (TraceDefaultMethods) { |
795 ResourceMark rm; |
817 ResourceMark rm; // be careful with these! |
796 log_debug(defaultmethods)("%s %s requires default method processing", |
818 tty->print_cr("%s %s requires default method processing", |
797 klass->is_interface() ? "Interface" : "Class", |
819 klass->is_interface() ? "Interface" : "Class", |
798 klass->name()->as_klass_external_name()); |
820 klass->name()->as_klass_external_name()); |
799 PrintHierarchy printer(LogHandle(defaultmethods)::debug_stream()); |
821 PrintHierarchy printer; |
|
822 printer.run(klass); |
800 printer.run(klass); |
823 } |
801 } |
824 #endif // ndef PRODUCT |
|
825 |
802 |
826 GrowableArray<EmptyVtableSlot*>* empty_slots = |
803 GrowableArray<EmptyVtableSlot*>* empty_slots = |
827 find_empty_vtable_slots(klass, mirandas, CHECK); |
804 find_empty_vtable_slots(klass, mirandas, CHECK); |
828 |
805 |
829 for (int i = 0; i < empty_slots->length(); ++i) { |
806 for (int i = 0; i < empty_slots->length(); ++i) { |
830 EmptyVtableSlot* slot = empty_slots->at(i); |
807 EmptyVtableSlot* slot = empty_slots->at(i); |
831 #ifndef PRODUCT |
808 if (log_is_enabled(Debug, defaultmethods)) { |
832 if (TraceDefaultMethods) { |
809 outputStream* logstream = LogHandle(defaultmethods)::debug_stream(); |
833 streamIndentor si(tty, 2); |
810 streamIndentor si(logstream, 2); |
834 tty->indent().print("Looking for default methods for slot "); |
811 logstream->indent().print("Looking for default methods for slot "); |
835 slot->print_on(tty); |
812 slot->print_on(logstream); |
836 tty->cr(); |
813 logstream->cr(); |
837 } |
814 } |
838 #endif // ndef PRODUCT |
|
839 |
|
840 generate_erased_defaults(klass, empty_slots, slot, CHECK); |
815 generate_erased_defaults(klass, empty_slots, slot, CHECK); |
841 } |
816 } |
842 #ifndef PRODUCT |
817 log_debug(defaultmethods)("Creating defaults and overpasses..."); |
843 if (TraceDefaultMethods) { |
|
844 tty->print_cr("Creating defaults and overpasses..."); |
|
845 } |
|
846 #endif // ndef PRODUCT |
|
847 |
|
848 create_defaults_and_exceptions(empty_slots, klass, CHECK); |
818 create_defaults_and_exceptions(empty_slots, klass, CHECK); |
849 |
819 log_debug(defaultmethods)("Default method processing complete"); |
850 #ifndef PRODUCT |
|
851 if (TraceDefaultMethods) { |
|
852 tty->print_cr("Default method processing complete"); |
|
853 } |
|
854 #endif // ndef PRODUCT |
|
855 } |
820 } |
856 |
821 |
857 static int assemble_method_error( |
822 static int assemble_method_error( |
858 BytecodeConstantPool* cp, BytecodeBuffer* buffer, Symbol* errorName, Symbol* message, TRAPS) { |
823 BytecodeConstantPool* cp, BytecodeBuffer* buffer, Symbol* errorName, Symbol* message, TRAPS) { |
859 |
824 |
945 |
910 |
946 if (slot->is_bound()) { |
911 if (slot->is_bound()) { |
947 MethodFamily* method = slot->get_binding(); |
912 MethodFamily* method = slot->get_binding(); |
948 BytecodeBuffer buffer; |
913 BytecodeBuffer buffer; |
949 |
914 |
950 #ifndef PRODUCT |
915 if (log_is_enabled(Debug, defaultmethods)) { |
951 if (TraceDefaultMethods) { |
916 ResourceMark rm; |
952 tty->print("for slot: "); |
917 outputStream* logstream = LogHandle(defaultmethods)::debug_stream(); |
953 slot->print_on(tty); |
918 logstream->print("for slot: "); |
954 tty->cr(); |
919 slot->print_on(logstream); |
|
920 logstream->cr(); |
955 if (method->has_target()) { |
921 if (method->has_target()) { |
956 method->print_selected(tty, 1); |
922 method->print_selected(logstream, 1); |
957 } else if (method->throws_exception()) { |
923 } else if (method->throws_exception()) { |
958 method->print_exception(tty, 1); |
924 method->print_exception(logstream, 1); |
959 } |
925 } |
960 } |
926 } |
961 #endif // ndef PRODUCT |
|
962 |
927 |
963 if (method->has_target()) { |
928 if (method->has_target()) { |
964 Method* selected = method->get_selected_target(); |
929 Method* selected = method->get_selected_target(); |
965 if (selected->method_holder()->is_interface()) { |
930 if (selected->method_holder()->is_interface()) { |
966 defaults.push(selected); |
931 defaults.push(selected); |
980 } |
945 } |
981 } |
946 } |
982 } |
947 } |
983 } |
948 } |
984 |
949 |
985 #ifndef PRODUCT |
950 |
986 if (TraceDefaultMethods) { |
951 log_debug(defaultmethods)("Created %d overpass methods", overpasses.length()); |
987 tty->print_cr("Created %d overpass methods", overpasses.length()); |
952 log_debug(defaultmethods)("Created %d default methods", defaults.length()); |
988 tty->print_cr("Created %d default methods", defaults.length()); |
|
989 } |
|
990 #endif // ndef PRODUCT |
|
991 |
953 |
992 if (overpasses.length() > 0) { |
954 if (overpasses.length() > 0) { |
993 switchover_constant_pool(&bpool, klass, &overpasses, CHECK); |
955 switchover_constant_pool(&bpool, klass, &overpasses, CHECK); |
994 merge_in_new_methods(klass, &overpasses, CHECK); |
956 merge_in_new_methods(klass, &overpasses, CHECK); |
995 } |
957 } |