624 {
625 oop_maps = generate_handle_exception(id, sasm);
626 __ leave();
627 __ ret(lr);
628 }
629 break;
630
631 case throw_div0_exception_id:
632 { StubFrame f(sasm, "throw_div0_exception", dont_gc_arguments, does_not_return);
633 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_div0_exception), false);
634 }
635 break;
636
637 case throw_null_pointer_exception_id:
638 { StubFrame f(sasm, "throw_null_pointer_exception", dont_gc_arguments, does_not_return);
639 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_null_pointer_exception), false);
640 }
641 break;
642
643 case new_instance_id:
644 case fast_new_instance_id:
645 case fast_new_instance_init_check_id:
646 {
647 Register klass = r3; // Incoming
648 Register obj = r0; // Result
649
650 if (id == new_instance_id) {
651 __ set_info("new_instance", dont_gc_arguments);
652 } else if (id == fast_new_instance_id) {
653 __ set_info("fast new_instance", dont_gc_arguments);
654 } else {
655 assert(id == fast_new_instance_init_check_id, "bad StubID");
656 __ set_info("fast new_instance init check", dont_gc_arguments);
657 }
658
659 __ enter();
660 OopMap* map = save_live_registers(sasm);
661 int call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_instance), klass);
662 oop_maps = new OopMapSet();
663 oop_maps->add_gc_map(call_offset, map);
664 restore_live_registers_except_r0(sasm);
665 __ verify_oop(obj);
666 __ leave();
667 __ ret(lr);
668
669 // r0,: new instance
670 }
671
672 break;
673
674 case counter_overflow_id:
675 {
676 Register bci = r0, method = r1;
677 __ enter();
678 OopMap* map = save_live_registers(sasm);
679 // Retrieve bci
680 __ ldrw(bci, Address(rfp, 2*BytesPerWord));
681 // And a pointer to the Method*
682 __ ldr(method, Address(rfp, 3*BytesPerWord));
683 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci, method);
684 oop_maps = new OopMapSet();
685 oop_maps->add_gc_map(call_offset, map);
686 restore_live_registers(sasm);
687 __ leave();
688 __ ret(lr);
689 }
690 break;
691
692 case new_type_array_id:
693 case new_object_array_id:
694 {
695 Register length = r19; // Incoming
696 Register klass = r3; // Incoming
697 Register obj = r0; // Result
698
699 if (id == new_type_array_id) {
700 __ set_info("new_type_array", dont_gc_arguments);
701 } else {
702 __ set_info("new_object_array", dont_gc_arguments);
703 }
704
705 #ifdef ASSERT
706 // assert object type is really an array of the proper kind
707 {
708 Label ok;
709 Register t0 = obj;
710 __ ldrw(t0, Address(klass, Klass::layout_helper_offset()));
711 __ asrw(t0, t0, Klass::_lh_array_tag_shift);
712 int tag = ((id == new_type_array_id)
713 ? Klass::_lh_array_tag_type_value
714 : Klass::_lh_array_tag_obj_value);
715 __ mov(rscratch1, tag);
716 __ cmpw(t0, rscratch1);
717 __ br(Assembler::EQ, ok);
718 __ stop("assert(is an array klass)");
719 __ should_not_reach_here();
720 __ bind(ok);
721 }
722 #endif // ASSERT
723
724 __ enter();
725 OopMap* map = save_live_registers(sasm);
726 int call_offset;
727 if (id == new_type_array_id) {
728 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_type_array), klass, length);
729 } else {
730 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_object_array), klass, length);
731 }
732
733 oop_maps = new OopMapSet();
734 oop_maps->add_gc_map(call_offset, map);
735 restore_live_registers_except_r0(sasm);
736
737 __ verify_oop(obj);
738 __ leave();
739 __ ret(lr);
740
741 // r0: new array
742 }
743 break;
744
745 case new_multi_array_id:
746 { StubFrame f(sasm, "new_multi_array", dont_gc_arguments);
747 // r0,: klass
748 // r19,: rank
749 // r2: address of 1st dimension
750 OopMap* map = save_live_registers(sasm);
751 __ mov(c_rarg1, r0);
752 __ mov(c_rarg3, r2);
753 __ mov(c_rarg2, r19);
754 int call_offset = __ call_RT(r0, noreg, CAST_FROM_FN_PTR(address, new_multi_array), r1, r2, r3);
755
756 oop_maps = new OopMapSet();
757 oop_maps->add_gc_map(call_offset, map);
758 restore_live_registers_except_r0(sasm);
759
760 // r0,: new multi array
761 __ verify_oop(r0);
762 }
763 break;
764
765 case register_finalizer_id:
766 {
767 __ set_info("register_finalizer", dont_gc_arguments);
768
769 // This is called via call_runtime so the arguments
770 // will be place in C abi locations
771
772 __ verify_oop(c_rarg0);
773
774 // load the klass and check the has finalizer flag
775 Label register_finalizer;
776 Register t = r5;
777 __ load_klass(t, r0);
778 __ ldrw(t, Address(t, Klass::access_flags_offset()));
779 __ tbnz(t, exact_log2(JVM_ACC_HAS_FINALIZER), register_finalizer);
780 __ ret(lr);
781
782 __ bind(register_finalizer);
783 __ enter();
784 OopMap* oop_map = save_live_registers(sasm);
785 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, SharedRuntime::register_finalizer), r0);
786 oop_maps = new OopMapSet();
787 oop_maps->add_gc_map(call_offset, oop_map);
788
789 // Now restore all the live registers
790 restore_live_registers(sasm);
791
792 __ leave();
793 __ ret(lr);
794 }
795 break;
796
797 case throw_class_cast_exception_id:
798 { StubFrame f(sasm, "throw_class_cast_exception", dont_gc_arguments, does_not_return);
799 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_class_cast_exception), true);
800 }
801 break;
802
803 case throw_incompatible_class_change_error_id:
804 { StubFrame f(sasm, "throw_incompatible_class_cast_exception", dont_gc_arguments, does_not_return);
805 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false);
806 }
807 break;
808
809 case slow_subtype_check_id:
810 {
811 // Typical calling sequence:
812 // __ push(klass_RInfo); // object klass or other subclass
813 // __ push(sup_k_RInfo); // array element klass or other superclass
814 // __ bl(slow_subtype_check);
815 // Note that the subclass is pushed first, and is therefore deepest.
816 enum layout {
817 r0_off, r0_off_hi,
818 r2_off, r2_off_hi,
819 r4_off, r4_off_hi,
820 r5_off, r5_off_hi,
821 sup_k_off, sup_k_off_hi,
822 klass_off, klass_off_hi,
823 framesize,
824 result_off = sup_k_off
825 };
826
827 __ set_info("slow_subtype_check", dont_gc_arguments);
828 __ push(RegSet::of(r0, r2, r4, r5), sp);
992 __ leave();
993 DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
994 assert(deopt_blob != nullptr, "deoptimization blob must have been created");
995
996 __ far_jump(RuntimeAddress(deopt_blob->unpack_with_reexecution()));
997 }
998 break;
999
1000 case dtrace_object_alloc_id:
1001 { // c_rarg0: object
1002 StubFrame f(sasm, "dtrace_object_alloc", dont_gc_arguments);
1003 save_live_registers(sasm);
1004
1005 __ call_VM_leaf(CAST_FROM_FN_PTR(address, static_cast<int (*)(oopDesc*)>(SharedRuntime::dtrace_object_alloc)), c_rarg0);
1006
1007 restore_live_registers(sasm);
1008 }
1009 break;
1010
1011 default:
1012 { StubFrame f(sasm, "unimplemented entry", dont_gc_arguments, does_not_return);
1013 __ mov(r0, (int)id);
1014 __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), r0);
1015 }
1016 break;
1017 }
1018 }
1019 return oop_maps;
1020 }
1021
1022 #undef __
1023
1024 const char *Runtime1::pd_name_for_address(address entry) { Unimplemented(); return 0; }
|
624 {
625 oop_maps = generate_handle_exception(id, sasm);
626 __ leave();
627 __ ret(lr);
628 }
629 break;
630
631 case throw_div0_exception_id:
632 { StubFrame f(sasm, "throw_div0_exception", dont_gc_arguments, does_not_return);
633 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_div0_exception), false);
634 }
635 break;
636
637 case throw_null_pointer_exception_id:
638 { StubFrame f(sasm, "throw_null_pointer_exception", dont_gc_arguments, does_not_return);
639 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_null_pointer_exception), false);
640 }
641 break;
642
643 case new_instance_id:
644 case new_instance_no_inline_id:
645 case fast_new_instance_id:
646 case fast_new_instance_init_check_id:
647 {
648 Register klass = r3; // Incoming
649 Register obj = r0; // Result
650
651 if (id == new_instance_id) {
652 __ set_info("new_instance", dont_gc_arguments);
653 } else if (id == new_instance_no_inline_id) {
654 __ set_info("new_instance_no_inline", dont_gc_arguments);
655 } else if (id == fast_new_instance_id) {
656 __ set_info("fast new_instance", dont_gc_arguments);
657 } else {
658 assert(id == fast_new_instance_init_check_id, "bad StubID");
659 __ set_info("fast new_instance init check", dont_gc_arguments);
660 }
661
662 __ enter();
663 OopMap* map = save_live_registers(sasm);
664 int call_offset;
665 if (id == new_instance_no_inline_id) {
666 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_instance_no_inline), klass);
667 } else {
668 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_instance), klass);
669 }
670 oop_maps = new OopMapSet();
671 oop_maps->add_gc_map(call_offset, map);
672 restore_live_registers_except_r0(sasm);
673 __ verify_oop(obj);
674 __ leave();
675 __ ret(lr);
676
677 // r0,: new instance
678 }
679
680 break;
681
682 case counter_overflow_id:
683 {
684 Register bci = r0, method = r1;
685 __ enter();
686 OopMap* map = save_live_registers(sasm);
687 // Retrieve bci
688 __ ldrw(bci, Address(rfp, 2*BytesPerWord));
689 // And a pointer to the Method*
690 __ ldr(method, Address(rfp, 3*BytesPerWord));
691 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci, method);
692 oop_maps = new OopMapSet();
693 oop_maps->add_gc_map(call_offset, map);
694 restore_live_registers(sasm);
695 __ leave();
696 __ ret(lr);
697 }
698 break;
699
700 case new_type_array_id:
701 case new_object_array_id:
702 case new_flat_array_id:
703 {
704 Register length = r19; // Incoming
705 Register klass = r3; // Incoming
706 Register obj = r0; // Result
707
708 if (id == new_type_array_id) {
709 __ set_info("new_type_array", dont_gc_arguments);
710 } else if (id == new_object_array_id) {
711 __ set_info("new_object_array", dont_gc_arguments);
712 } else {
713 __ set_info("new_flat_array", dont_gc_arguments);
714 }
715
716 #ifdef ASSERT
717 // assert object type is really an array of the proper kind
718 {
719 Label ok;
720 Register t0 = obj;
721 __ ldrw(t0, Address(klass, Klass::layout_helper_offset()));
722 __ asrw(t0, t0, Klass::_lh_array_tag_shift);
723 switch (id) {
724 case new_type_array_id:
725 __ cmpw(t0, Klass::_lh_array_tag_type_value);
726 __ br(Assembler::EQ, ok);
727 __ stop("assert(is a type array klass)");
728 break;
729 case new_object_array_id:
730 __ cmpw(t0, Klass::_lh_array_tag_obj_value); // new "[Ljava/lang/Object;"
731 __ br(Assembler::EQ, ok);
732 __ cmpw(t0, Klass::_lh_array_tag_vt_value); // new "[LVT;"
733 __ br(Assembler::EQ, ok);
734 __ stop("assert(is an object or inline type array klass)");
735 break;
736 case new_flat_array_id:
737 // new "[QVT;"
738 __ cmpw(t0, Klass::_lh_array_tag_vt_value); // the array can be flattened.
739 __ br(Assembler::EQ, ok);
740 __ cmpw(t0, Klass::_lh_array_tag_obj_value); // the array cannot be flattened (due to InlineArrayElementMaxFlatSize, etc)
741 __ br(Assembler::EQ, ok);
742 __ stop("assert(is an object or inline type array klass)");
743 break;
744 default: ShouldNotReachHere();
745 }
746 __ should_not_reach_here();
747 __ bind(ok);
748 }
749 #endif // ASSERT
750
751 __ enter();
752 OopMap* map = save_live_registers(sasm);
753 int call_offset;
754 if (id == new_type_array_id) {
755 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_type_array), klass, length);
756 } else if (id == new_object_array_id) {
757 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_object_array), klass, length);
758 } else {
759 assert(id == new_flat_array_id, "must be");
760 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_flat_array), klass, length);
761 }
762
763 oop_maps = new OopMapSet();
764 oop_maps->add_gc_map(call_offset, map);
765 restore_live_registers_except_r0(sasm);
766
767 __ verify_oop(obj);
768 __ leave();
769 __ ret(lr);
770
771 // r0: new array
772 }
773 break;
774
775 case new_multi_array_id:
776 { StubFrame f(sasm, "new_multi_array", dont_gc_arguments);
777 // r0,: klass
778 // r19,: rank
779 // r2: address of 1st dimension
780 OopMap* map = save_live_registers(sasm);
781 __ mov(c_rarg1, r0);
782 __ mov(c_rarg3, r2);
783 __ mov(c_rarg2, r19);
784 int call_offset = __ call_RT(r0, noreg, CAST_FROM_FN_PTR(address, new_multi_array), r1, r2, r3);
785
786 oop_maps = new OopMapSet();
787 oop_maps->add_gc_map(call_offset, map);
788 restore_live_registers_except_r0(sasm);
789
790 // r0,: new multi array
791 __ verify_oop(r0);
792 }
793 break;
794
795 case buffer_inline_args_id:
796 case buffer_inline_args_no_receiver_id:
797 {
798 const char* name = (id == buffer_inline_args_id) ?
799 "buffer_inline_args" : "buffer_inline_args_no_receiver";
800 StubFrame f(sasm, name, dont_gc_arguments);
801 OopMap* map = save_live_registers(sasm);
802 Register method = r19; // Incoming
803 address entry = (id == buffer_inline_args_id) ?
804 CAST_FROM_FN_PTR(address, buffer_inline_args) :
805 CAST_FROM_FN_PTR(address, buffer_inline_args_no_receiver);
806 // This is called from a C1 method's scalarized entry point
807 // where r0-r7 may be holding live argument values so we can't
808 // return the result in r0 as the other stubs do. LR is used as
809 // a temporay below to avoid the result being clobbered by
810 // restore_live_registers.
811 int call_offset = __ call_RT(lr, noreg, entry, method);
812 oop_maps = new OopMapSet();
813 oop_maps->add_gc_map(call_offset, map);
814 restore_live_registers(sasm);
815 __ mov(r20, lr);
816 __ verify_oop(r20); // r20: an array of buffered value objects
817 }
818 break;
819
820 case load_flattened_array_id:
821 {
822 StubFrame f(sasm, "load_flattened_array", dont_gc_arguments);
823 OopMap* map = save_live_registers(sasm);
824
825 // Called with store_parameter and not C abi
826
827 f.load_argument(1, r0); // r0,: array
828 f.load_argument(0, r1); // r1,: index
829 int call_offset = __ call_RT(r0, noreg, CAST_FROM_FN_PTR(address, load_flattened_array), r0, r1);
830
831 oop_maps = new OopMapSet();
832 oop_maps->add_gc_map(call_offset, map);
833 restore_live_registers_except_r0(sasm);
834
835 // r0: loaded element at array[index]
836 __ verify_oop(r0);
837 }
838 break;
839
840 case store_flattened_array_id:
841 {
842 StubFrame f(sasm, "store_flattened_array", dont_gc_arguments);
843 OopMap* map = save_live_registers(sasm, 4);
844
845 // Called with store_parameter and not C abi
846
847 f.load_argument(2, r0); // r0: array
848 f.load_argument(1, r1); // r1: index
849 f.load_argument(0, r2); // r2: value
850 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, store_flattened_array), r0, r1, r2);
851
852 oop_maps = new OopMapSet();
853 oop_maps->add_gc_map(call_offset, map);
854 restore_live_registers_except_r0(sasm);
855 }
856 break;
857
858 case substitutability_check_id:
859 {
860 StubFrame f(sasm, "substitutability_check", dont_gc_arguments);
861 OopMap* map = save_live_registers(sasm);
862
863 // Called with store_parameter and not C abi
864
865 f.load_argument(1, r1); // r1,: left
866 f.load_argument(0, r2); // r2,: right
867 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, substitutability_check), r1, r2);
868
869 oop_maps = new OopMapSet();
870 oop_maps->add_gc_map(call_offset, map);
871 restore_live_registers_except_r0(sasm);
872
873 // r0,: are the two operands substitutable
874 }
875 break;
876
877 case register_finalizer_id:
878 {
879 __ set_info("register_finalizer", dont_gc_arguments);
880
881 // This is called via call_runtime so the arguments
882 // will be place in C abi locations
883
884 __ verify_oop(c_rarg0);
885
886 // load the klass and check the has finalizer flag
887 Label register_finalizer;
888 Register t = r5;
889 __ load_klass(t, r0);
890 __ ldrw(t, Address(t, Klass::access_flags_offset()));
891 __ tbnz(t, exact_log2(JVM_ACC_HAS_FINALIZER), register_finalizer);
892 __ ret(lr);
893
894 __ bind(register_finalizer);
895 __ enter();
896 OopMap* oop_map = save_live_registers(sasm);
897 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, SharedRuntime::register_finalizer), r0);
898 oop_maps = new OopMapSet();
899 oop_maps->add_gc_map(call_offset, oop_map);
900
901 // Now restore all the live registers
902 restore_live_registers(sasm);
903
904 __ leave();
905 __ ret(lr);
906 }
907 break;
908
909 case throw_class_cast_exception_id:
910 { StubFrame f(sasm, "throw_class_cast_exception", dont_gc_arguments, does_not_return);
911 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_class_cast_exception), true);
912 }
913 break;
914
915 case throw_incompatible_class_change_error_id:
916 { StubFrame f(sasm, "throw_incompatible_class_change_error", dont_gc_arguments, does_not_return);
917 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false);
918 }
919 break;
920
921 case throw_illegal_monitor_state_exception_id:
922 { StubFrame f(sasm, "throw_illegal_monitor_state_exception", dont_gc_arguments);
923 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_illegal_monitor_state_exception), false);
924 }
925 break;
926
927 case slow_subtype_check_id:
928 {
929 // Typical calling sequence:
930 // __ push(klass_RInfo); // object klass or other subclass
931 // __ push(sup_k_RInfo); // array element klass or other superclass
932 // __ bl(slow_subtype_check);
933 // Note that the subclass is pushed first, and is therefore deepest.
934 enum layout {
935 r0_off, r0_off_hi,
936 r2_off, r2_off_hi,
937 r4_off, r4_off_hi,
938 r5_off, r5_off_hi,
939 sup_k_off, sup_k_off_hi,
940 klass_off, klass_off_hi,
941 framesize,
942 result_off = sup_k_off
943 };
944
945 __ set_info("slow_subtype_check", dont_gc_arguments);
946 __ push(RegSet::of(r0, r2, r4, r5), sp);
1110 __ leave();
1111 DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
1112 assert(deopt_blob != nullptr, "deoptimization blob must have been created");
1113
1114 __ far_jump(RuntimeAddress(deopt_blob->unpack_with_reexecution()));
1115 }
1116 break;
1117
1118 case dtrace_object_alloc_id:
1119 { // c_rarg0: object
1120 StubFrame f(sasm, "dtrace_object_alloc", dont_gc_arguments);
1121 save_live_registers(sasm);
1122
1123 __ call_VM_leaf(CAST_FROM_FN_PTR(address, static_cast<int (*)(oopDesc*)>(SharedRuntime::dtrace_object_alloc)), c_rarg0);
1124
1125 restore_live_registers(sasm);
1126 }
1127 break;
1128
1129 default:
1130 // FIXME: For unhandled trap_id this code fails with assert during vm intialization
1131 // rather than insert a call to unimplemented_entry
1132 { StubFrame f(sasm, "unimplemented entry", dont_gc_arguments, does_not_return);
1133 __ mov(r0, (int)id);
1134 __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), r0);
1135 }
1136 break;
1137 }
1138 }
1139
1140
1141 return oop_maps;
1142 }
1143
1144 #undef __
1145
1146 const char *Runtime1::pd_name_for_address(address entry) { Unimplemented(); return 0; }
|