691 break;
692
693 case StubId::c1_new_instance_id:
694 case StubId::c1_fast_new_instance_id:
695 case StubId::c1_fast_new_instance_init_check_id:
696 {
697 Register klass = r3; // Incoming
698 Register obj = r0; // Result
699
700 if (id == StubId::c1_new_instance_id) {
701 __ set_info("new_instance", dont_gc_arguments);
702 } else if (id == StubId::c1_fast_new_instance_id) {
703 __ set_info("fast new_instance", dont_gc_arguments);
704 } else {
705 assert(id == StubId::c1_fast_new_instance_init_check_id, "bad StubId");
706 __ set_info("fast new_instance init check", dont_gc_arguments);
707 }
708
709 __ enter();
710 OopMap* map = save_live_registers(sasm);
711 int call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_instance), klass);
712 oop_maps = new OopMapSet();
713 oop_maps->add_gc_map(call_offset, map);
714 restore_live_registers_except_r0(sasm);
715 __ verify_oop(obj);
716 __ leave();
717 __ ret(lr);
718
719 // r0,: new instance
720 }
721
722 break;
723
724 case StubId::c1_counter_overflow_id:
725 {
726 Register bci = r0, method = r1;
727 __ enter();
728 OopMap* map = save_live_registers(sasm);
729 // Retrieve bci
730 __ ldrw(bci, Address(rfp, 2*BytesPerWord));
731 // And a pointer to the Method*
732 __ ldr(method, Address(rfp, 3*BytesPerWord));
733 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci, method);
734 oop_maps = new OopMapSet();
735 oop_maps->add_gc_map(call_offset, map);
736 restore_live_registers(sasm);
737 __ leave();
738 __ ret(lr);
739 }
740 break;
741
742 case StubId::c1_new_type_array_id:
743 case StubId::c1_new_object_array_id:
744 {
745 Register length = r19; // Incoming
746 Register klass = r3; // Incoming
747 Register obj = r0; // Result
748
749 if (id == StubId::c1_new_type_array_id) {
750 __ set_info("new_type_array", dont_gc_arguments);
751 } else {
752 __ set_info("new_object_array", dont_gc_arguments);
753 }
754
755 #ifdef ASSERT
756 // assert object type is really an array of the proper kind
757 {
758 Label ok;
759 Register t0 = obj;
760 __ ldrw(t0, Address(klass, Klass::layout_helper_offset()));
761 __ asrw(t0, t0, Klass::_lh_array_tag_shift);
762 int tag = ((id == StubId::c1_new_type_array_id)
763 ? Klass::_lh_array_tag_type_value
764 : Klass::_lh_array_tag_obj_value);
765 __ mov(rscratch1, tag);
766 __ cmpw(t0, rscratch1);
767 __ br(Assembler::EQ, ok);
768 __ stop("assert(is an array klass)");
769 __ should_not_reach_here();
770 __ bind(ok);
771 }
772 #endif // ASSERT
773
774 __ enter();
775 OopMap* map = save_live_registers(sasm);
776 int call_offset;
777 if (id == StubId::c1_new_type_array_id) {
778 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_type_array), klass, length);
779 } else {
780 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_object_array), klass, length);
781 }
782
783 oop_maps = new OopMapSet();
784 oop_maps->add_gc_map(call_offset, map);
785 restore_live_registers_except_r0(sasm);
786
787 __ verify_oop(obj);
788 __ leave();
789 __ ret(lr);
790
791 // r0: new array
792 }
793 break;
794
795 case StubId::c1_new_multi_array_id:
796 { StubFrame f(sasm, "new_multi_array", dont_gc_arguments);
797 // r0,: klass
798 // r19,: rank
799 // r2: address of 1st dimension
800 OopMap* map = save_live_registers(sasm);
801 __ mov(c_rarg1, r0);
802 __ mov(c_rarg3, r2);
803 __ mov(c_rarg2, r19);
804 int call_offset = __ call_RT(r0, noreg, CAST_FROM_FN_PTR(address, new_multi_array), r1, r2, r3);
805
806 oop_maps = new OopMapSet();
807 oop_maps->add_gc_map(call_offset, map);
808 restore_live_registers_except_r0(sasm);
809
810 // r0,: new multi array
811 __ verify_oop(r0);
812 }
813 break;
814
815 case StubId::c1_register_finalizer_id:
816 {
817 __ set_info("register_finalizer", dont_gc_arguments);
818
819 // This is called via call_runtime so the arguments
820 // will be place in C abi locations
821
822 __ verify_oop(c_rarg0);
823
824 // load the klass and check the has finalizer flag
825 Label register_finalizer;
826 Register t = r5;
827 __ load_klass(t, r0);
828 __ ldrb(t, Address(t, Klass::misc_flags_offset()));
829 __ tbnz(t, exact_log2(KlassFlags::_misc_has_finalizer), register_finalizer);
830 __ ret(lr);
831
832 __ bind(register_finalizer);
833 __ enter();
834 OopMap* oop_map = save_live_registers(sasm);
835 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, SharedRuntime::register_finalizer), r0);
836 oop_maps = new OopMapSet();
837 oop_maps->add_gc_map(call_offset, oop_map);
838
839 // Now restore all the live registers
840 restore_live_registers(sasm);
841
842 __ leave();
843 __ ret(lr);
844 }
845 break;
846
847 case StubId::c1_throw_class_cast_exception_id:
848 { StubFrame f(sasm, "throw_class_cast_exception", dont_gc_arguments, does_not_return);
849 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_class_cast_exception), true);
850 }
851 break;
852
853 case StubId::c1_throw_incompatible_class_change_error_id:
854 { StubFrame f(sasm, "throw_incompatible_class_cast_exception", dont_gc_arguments, does_not_return);
855 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false);
856 }
857 break;
858
859 case StubId::c1_slow_subtype_check_id:
860 {
861 // Typical calling sequence:
862 // __ push(klass_RInfo); // object klass or other subclass
863 // __ push(sup_k_RInfo); // array element klass or other superclass
864 // __ bl(slow_subtype_check);
865 // Note that the subclass is pushed first, and is therefore deepest.
866 enum layout {
867 r0_off, r0_off_hi,
868 r2_off, r2_off_hi,
869 r4_off, r4_off_hi,
870 r5_off, r5_off_hi,
871 sup_k_off, sup_k_off_hi,
872 klass_off, klass_off_hi,
873 framesize,
874 result_off = sup_k_off
875 };
876
877 __ set_info("slow_subtype_check", dont_gc_arguments);
878 __ push(RegSet::of(r0, r2, r4, r5), sp);
1097 __ leave();
1098 DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
1099 assert(deopt_blob != nullptr, "deoptimization blob must have been created");
1100
1101 __ far_jump(RuntimeAddress(deopt_blob->unpack_with_reexecution()));
1102 }
1103 break;
1104
1105 case StubId::c1_dtrace_object_alloc_id:
1106 { // c_rarg0: object
1107 StubFrame f(sasm, "dtrace_object_alloc", dont_gc_arguments);
1108 save_live_registers(sasm);
1109
1110 __ call_VM_leaf(CAST_FROM_FN_PTR(address, static_cast<int (*)(oopDesc*)>(SharedRuntime::dtrace_object_alloc)), c_rarg0);
1111
1112 restore_live_registers(sasm);
1113 }
1114 break;
1115
1116 default:
1117 { StubFrame f(sasm, "unimplemented entry", dont_gc_arguments, does_not_return);
1118 __ mov(r0, (int)id);
1119 __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), r0);
1120 }
1121 break;
1122 }
1123 }
1124 return oop_maps;
1125 }
1126
1127 #undef __
1128
1129 const char *Runtime1::pd_name_for_address(address entry) { Unimplemented(); }
|
691 break;
692
693 case StubId::c1_new_instance_id:
694 case StubId::c1_fast_new_instance_id:
695 case StubId::c1_fast_new_instance_init_check_id:
696 {
697 Register klass = r3; // Incoming
698 Register obj = r0; // Result
699
700 if (id == StubId::c1_new_instance_id) {
701 __ set_info("new_instance", dont_gc_arguments);
702 } else if (id == StubId::c1_fast_new_instance_id) {
703 __ set_info("fast new_instance", dont_gc_arguments);
704 } else {
705 assert(id == StubId::c1_fast_new_instance_init_check_id, "bad StubId");
706 __ set_info("fast new_instance init check", dont_gc_arguments);
707 }
708
709 __ enter();
710 OopMap* map = save_live_registers(sasm);
711 int call_offset;
712 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_instance), klass);
713 oop_maps = new OopMapSet();
714 oop_maps->add_gc_map(call_offset, map);
715 restore_live_registers_except_r0(sasm);
716 __ verify_oop(obj);
717 __ leave();
718 __ ret(lr);
719
720 // r0,: new instance
721 }
722
723 break;
724
725 case StubId::c1_counter_overflow_id:
726 {
727 Register bci = r0, method = r1;
728 __ enter();
729 OopMap* map = save_live_registers(sasm);
730 // Retrieve bci
731 __ ldrw(bci, Address(rfp, 2*BytesPerWord));
732 // And a pointer to the Method*
733 __ ldr(method, Address(rfp, 3*BytesPerWord));
734 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci, method);
735 oop_maps = new OopMapSet();
736 oop_maps->add_gc_map(call_offset, map);
737 restore_live_registers(sasm);
738 __ leave();
739 __ ret(lr);
740 }
741 break;
742
743 case StubId::c1_new_type_array_id:
744 case StubId::c1_new_object_array_id:
745 case StubId::c1_new_null_free_array_id:
746 {
747 Register length = r19; // Incoming
748 Register klass = r3; // Incoming
749 Register obj = r0; // Result
750
751 if (id == StubId::c1_new_type_array_id) {
752 __ set_info("new_type_array", dont_gc_arguments);
753 } else if (id == StubId::c1_new_object_array_id) {
754 __ set_info("new_object_array", dont_gc_arguments);
755 } else {
756 __ set_info("new_null_free_array", dont_gc_arguments);
757 }
758
759 #ifdef ASSERT
760 // assert object type is really an array of the proper kind
761 {
762 Label ok;
763 Register t0 = obj;
764 __ ldrw(t0, Address(klass, Klass::layout_helper_offset()));
765 __ asrw(t0, t0, Klass::_lh_array_tag_shift);
766 switch (id) {
767 case StubId::c1_new_type_array_id:
768 __ cmpw(t0, Klass::_lh_array_tag_type_value);
769 __ br(Assembler::EQ, ok);
770 __ stop("assert(is a type array klass)");
771 break;
772 case StubId::c1_new_object_array_id:
773 __ cmpw(t0, Klass::_lh_array_tag_ref_value); // new "[Ljava/lang/Object;"
774 __ br(Assembler::EQ, ok);
775 __ cmpw(t0, Klass::_lh_array_tag_flat_value); // new "[LVT;"
776 __ br(Assembler::EQ, ok);
777 __ stop("assert(is an object or inline type array klass)");
778 break;
779 case StubId::c1_new_null_free_array_id:
780 __ cmpw(t0, Klass::_lh_array_tag_flat_value); // the array can be a flat array.
781 __ br(Assembler::EQ, ok);
782 __ cmpw(t0, Klass::_lh_array_tag_ref_value); // the array cannot be a flat array (due to the InlineArrayElementMaxFlatSize, etc.)
783 __ br(Assembler::EQ, ok);
784 __ stop("assert(is an object or inline type array klass)");
785 break;
786 default: ShouldNotReachHere();
787 }
788 __ should_not_reach_here();
789 __ bind(ok);
790 }
791 #endif // ASSERT
792
793 __ enter();
794 OopMap* map = save_live_registers(sasm);
795 int call_offset;
796 if (id == StubId::c1_new_type_array_id) {
797 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_type_array), klass, length);
798 } else if (id == StubId::c1_new_object_array_id) {
799 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_object_array), klass, length);
800 } else {
801 assert(id == StubId::c1_new_null_free_array_id, "must be");
802 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_null_free_array), klass, length);
803 }
804
805 oop_maps = new OopMapSet();
806 oop_maps->add_gc_map(call_offset, map);
807 restore_live_registers_except_r0(sasm);
808
809 __ verify_oop(obj);
810 __ leave();
811 __ ret(lr);
812
813 // r0: new array
814 }
815 break;
816
817 case StubId::c1_new_multi_array_id:
818 { StubFrame f(sasm, "new_multi_array", dont_gc_arguments);
819 // r0,: klass
820 // r19,: rank
821 // r2: address of 1st dimension
822 OopMap* map = save_live_registers(sasm);
823 __ mov(c_rarg1, r0);
824 __ mov(c_rarg3, r2);
825 __ mov(c_rarg2, r19);
826 int call_offset = __ call_RT(r0, noreg, CAST_FROM_FN_PTR(address, new_multi_array), r1, r2, r3);
827
828 oop_maps = new OopMapSet();
829 oop_maps->add_gc_map(call_offset, map);
830 restore_live_registers_except_r0(sasm);
831
832 // r0,: new multi array
833 __ verify_oop(r0);
834 }
835 break;
836
837 case StubId::c1_buffer_inline_args_id:
838 case StubId::c1_buffer_inline_args_no_receiver_id:
839 {
840 const char* name = (id == StubId::c1_buffer_inline_args_id) ?
841 "buffer_inline_args" : "buffer_inline_args_no_receiver";
842 StubFrame f(sasm, name, dont_gc_arguments);
843 OopMap* map = save_live_registers(sasm);
844 Register method = r19; // Incoming
845 address entry = (id == StubId::c1_buffer_inline_args_id) ?
846 CAST_FROM_FN_PTR(address, buffer_inline_args) :
847 CAST_FROM_FN_PTR(address, buffer_inline_args_no_receiver);
848 // This is called from a C1 method's scalarized entry point
849 // where r0-r7 may be holding live argument values so we can't
850 // return the result in r0 as the other stubs do. LR is used as
851 // a temporary below to avoid the result being clobbered by
852 // restore_live_registers. It's saved and restored by
853 // StubAssembler::prologue and epilogue anyway.
854 int call_offset = __ call_RT(lr, noreg, entry, method);
855 oop_maps = new OopMapSet();
856 oop_maps->add_gc_map(call_offset, map);
857 restore_live_registers(sasm);
858 __ mov(r20, lr);
859 __ verify_oop(r20); // r20: an array of buffered value objects
860 }
861 break;
862
863 case StubId::c1_load_flat_array_id:
864 {
865 StubFrame f(sasm, "load_flat_array", dont_gc_arguments);
866 OopMap* map = save_live_registers(sasm);
867
868 // Called with store_parameter and not C abi
869
870 f.load_argument(1, r0); // r0,: array
871 f.load_argument(0, r1); // r1,: index
872 int call_offset = __ call_RT(r0, noreg, CAST_FROM_FN_PTR(address, load_flat_array), r0, r1);
873
874 // Ensure the stores that initialize the buffer are visible
875 // before any subsequent store that publishes this reference.
876 __ membar(Assembler::StoreStore);
877
878 oop_maps = new OopMapSet();
879 oop_maps->add_gc_map(call_offset, map);
880 restore_live_registers_except_r0(sasm);
881
882 // r0: loaded element at array[index]
883 __ verify_oop(r0);
884 }
885 break;
886
887 case StubId::c1_store_flat_array_id:
888 {
889 StubFrame f(sasm, "store_flat_array", dont_gc_arguments);
890 OopMap* map = save_live_registers(sasm);
891
892 // Called with store_parameter and not C abi
893
894 f.load_argument(2, r0); // r0: array
895 f.load_argument(1, r1); // r1: index
896 f.load_argument(0, r2); // r2: value
897 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, store_flat_array), r0, r1, r2);
898
899 oop_maps = new OopMapSet();
900 oop_maps->add_gc_map(call_offset, map);
901 restore_live_registers_except_r0(sasm);
902 }
903 break;
904
905 case StubId::c1_substitutability_check_id:
906 {
907 StubFrame f(sasm, "substitutability_check", dont_gc_arguments);
908 OopMap* map = save_live_registers(sasm);
909
910 // Called with store_parameter and not C abi
911
912 f.load_argument(1, r1); // r1,: left
913 f.load_argument(0, r2); // r2,: right
914 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, substitutability_check), r1, r2);
915
916 oop_maps = new OopMapSet();
917 oop_maps->add_gc_map(call_offset, map);
918 restore_live_registers_except_r0(sasm);
919
920 // r0,: are the two operands substitutable
921 }
922 break;
923
924 case StubId::c1_register_finalizer_id:
925 {
926 __ set_info("register_finalizer", dont_gc_arguments);
927
928 // This is called via call_runtime so the arguments
929 // will be place in C abi locations
930
931 __ verify_oop(c_rarg0);
932
933 // load the klass and check the has finalizer flag
934 Label register_finalizer;
935 Register t = r5;
936 __ load_klass(t, r0);
937 __ ldrb(t, Address(t, Klass::misc_flags_offset()));
938 __ tbnz(t, exact_log2(KlassFlags::_misc_has_finalizer), register_finalizer);
939 __ ret(lr);
940
941 __ bind(register_finalizer);
942 __ enter();
943 OopMap* oop_map = save_live_registers(sasm);
944 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, SharedRuntime::register_finalizer), r0);
945 oop_maps = new OopMapSet();
946 oop_maps->add_gc_map(call_offset, oop_map);
947
948 // Now restore all the live registers
949 restore_live_registers(sasm);
950
951 __ leave();
952 __ ret(lr);
953 }
954 break;
955
956 case StubId::c1_throw_class_cast_exception_id:
957 { StubFrame f(sasm, "throw_class_cast_exception", dont_gc_arguments, does_not_return);
958 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_class_cast_exception), true);
959 }
960 break;
961
962 case StubId::c1_throw_incompatible_class_change_error_id:
963 { StubFrame f(sasm, "throw_incompatible_class_change_error", dont_gc_arguments, does_not_return);
964 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false);
965 }
966 break;
967
968 case StubId::c1_throw_illegal_monitor_state_exception_id:
969 { StubFrame f(sasm, "throw_illegal_monitor_state_exception", dont_gc_arguments);
970 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_illegal_monitor_state_exception), false);
971 }
972 break;
973
974 case StubId::c1_throw_identity_exception_id:
975 { StubFrame f(sasm, "throw_identity_exception", dont_gc_arguments);
976 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_identity_exception), true);
977 }
978 break;
979
980 case StubId::c1_slow_subtype_check_id:
981 {
982 // Typical calling sequence:
983 // __ push(klass_RInfo); // object klass or other subclass
984 // __ push(sup_k_RInfo); // array element klass or other superclass
985 // __ bl(slow_subtype_check);
986 // Note that the subclass is pushed first, and is therefore deepest.
987 enum layout {
988 r0_off, r0_off_hi,
989 r2_off, r2_off_hi,
990 r4_off, r4_off_hi,
991 r5_off, r5_off_hi,
992 sup_k_off, sup_k_off_hi,
993 klass_off, klass_off_hi,
994 framesize,
995 result_off = sup_k_off
996 };
997
998 __ set_info("slow_subtype_check", dont_gc_arguments);
999 __ push(RegSet::of(r0, r2, r4, r5), sp);
1218 __ leave();
1219 DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
1220 assert(deopt_blob != nullptr, "deoptimization blob must have been created");
1221
1222 __ far_jump(RuntimeAddress(deopt_blob->unpack_with_reexecution()));
1223 }
1224 break;
1225
1226 case StubId::c1_dtrace_object_alloc_id:
1227 { // c_rarg0: object
1228 StubFrame f(sasm, "dtrace_object_alloc", dont_gc_arguments);
1229 save_live_registers(sasm);
1230
1231 __ call_VM_leaf(CAST_FROM_FN_PTR(address, static_cast<int (*)(oopDesc*)>(SharedRuntime::dtrace_object_alloc)), c_rarg0);
1232
1233 restore_live_registers(sasm);
1234 }
1235 break;
1236
1237 default:
1238 // FIXME: For unhandled trap_id this code fails with assert during vm intialization
1239 // rather than insert a call to unimplemented_entry
1240 { StubFrame f(sasm, "unimplemented entry", dont_gc_arguments, does_not_return);
1241 __ mov(r0, (int)id);
1242 __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), r0);
1243 }
1244 break;
1245 }
1246 }
1247
1248
1249 return oop_maps;
1250 }
1251
1252 #undef __
1253
1254 const char *Runtime1::pd_name_for_address(address entry) { Unimplemented(); }
|