756 case counter_overflow_id:
757 {
758 Register bci = r0, method = r1;
759 __ enter();
760 OopMap* map = save_live_registers(sasm);
761 // Retrieve bci
762 __ ldrw(bci, Address(rfp, 2*BytesPerWord));
763 // And a pointer to the Method*
764 __ ldr(method, Address(rfp, 3*BytesPerWord));
765 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci, method);
766 oop_maps = new OopMapSet();
767 oop_maps->add_gc_map(call_offset, map);
768 restore_live_registers(sasm);
769 __ leave();
770 __ ret(lr);
771 }
772 break;
773
774 case new_type_array_id:
775 case new_object_array_id:
776 {
777 Register length = r19; // Incoming
778 Register klass = r3; // Incoming
779 Register obj = r0; // Result
780
781 if (id == new_type_array_id) {
782 __ set_info("new_type_array", dont_gc_arguments);
783 } else {
784 __ set_info("new_object_array", dont_gc_arguments);
785 }
786
787 #ifdef ASSERT
788 // assert object type is really an array of the proper kind
789 {
790 Label ok;
791 Register t0 = obj;
792 __ ldrw(t0, Address(klass, Klass::layout_helper_offset()));
793 __ asrw(t0, t0, Klass::_lh_array_tag_shift);
794 int tag = ((id == new_type_array_id)
795 ? Klass::_lh_array_tag_type_value
796 : Klass::_lh_array_tag_obj_value);
797 __ mov(rscratch1, tag);
798 __ cmpw(t0, rscratch1);
799 __ br(Assembler::EQ, ok);
800 __ stop("assert(is an array klass)");
801 __ should_not_reach_here();
802 __ bind(ok);
803 }
804 #endif // ASSERT
805
806 // If TLAB is disabled, see if there is support for inlining contiguous
807 // allocations.
808 // Otherwise, just go to the slow path.
809 if (!UseTLAB && Universe::heap()->supports_inline_contig_alloc()) {
810 Register arr_size = r4;
811 Register t1 = r2;
812 Register t2 = r5;
813 Label slow_path;
814 assert_different_registers(length, klass, obj, arr_size, t1, t2);
815
816 // check that array length is small enough for fast path.
836 __ ldrb(t1, Address(klass, in_bytes(Klass::layout_helper_offset()) + (Klass::_lh_header_size_shift / BitsPerByte)));
837 assert(Klass::_lh_header_size_shift % BitsPerByte == 0, "bytewise");
838 assert(Klass::_lh_header_size_mask <= 0xFF, "bytewise");
839 __ andr(t1, t1, Klass::_lh_header_size_mask);
840 __ sub(arr_size, arr_size, t1); // body length
841 __ add(t1, t1, obj); // body start
842 __ initialize_body(t1, arr_size, 0, t2);
843 __ verify_oop(obj);
844
845 __ ret(lr);
846
847 __ bind(slow_path);
848 }
849
850 __ enter();
851 OopMap* map = save_live_registers(sasm);
852 int call_offset;
853 if (id == new_type_array_id) {
854 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_type_array), klass, length);
855 } else {
856 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_object_array), klass, length);
857 }
858
859 oop_maps = new OopMapSet();
860 oop_maps->add_gc_map(call_offset, map);
861 restore_live_registers_except_r0(sasm);
862
863 __ verify_oop(obj);
864 __ leave();
865 __ ret(lr);
866
867 // r0: new array
868 }
869 break;
870
871 case new_multi_array_id:
872 { StubFrame f(sasm, "new_multi_array", dont_gc_arguments);
873 // r0,: klass
874 // r19,: rank
875 // r2: address of 1st dimension
876 OopMap* map = save_live_registers(sasm);
877 __ mov(c_rarg1, r0);
878 __ mov(c_rarg3, r2);
879 __ mov(c_rarg2, r19);
880 int call_offset = __ call_RT(r0, noreg, CAST_FROM_FN_PTR(address, new_multi_array), r1, r2, r3);
881
882 oop_maps = new OopMapSet();
883 oop_maps->add_gc_map(call_offset, map);
884 restore_live_registers_except_r0(sasm);
885
886 // r0,: new multi array
887 __ verify_oop(r0);
888 }
889 break;
890
891 case register_finalizer_id:
892 {
893 __ set_info("register_finalizer", dont_gc_arguments);
894
895 // This is called via call_runtime so the arguments
896 // will be place in C abi locations
897
898 __ verify_oop(c_rarg0);
899
900 // load the klass and check the has finalizer flag
901 Label register_finalizer;
902 Register t = r5;
903 __ load_klass(t, r0);
904 __ ldrw(t, Address(t, Klass::access_flags_offset()));
905 __ tbnz(t, exact_log2(JVM_ACC_HAS_FINALIZER), register_finalizer);
906 __ ret(lr);
907
908 __ bind(register_finalizer);
909 __ enter();
910 OopMap* oop_map = save_live_registers(sasm);
911 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, SharedRuntime::register_finalizer), r0);
912 oop_maps = new OopMapSet();
913 oop_maps->add_gc_map(call_offset, oop_map);
914
915 // Now restore all the live registers
916 restore_live_registers(sasm);
917
918 __ leave();
919 __ ret(lr);
920 }
921 break;
922
923 case throw_class_cast_exception_id:
924 { StubFrame f(sasm, "throw_class_cast_exception", dont_gc_arguments);
925 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_class_cast_exception), true);
926 }
927 break;
928
929 case throw_incompatible_class_change_error_id:
930 { StubFrame f(sasm, "throw_incompatible_class_cast_exception", dont_gc_arguments);
931 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false);
932 }
933 break;
934
935 case slow_subtype_check_id:
936 {
937 // Typical calling sequence:
938 // __ push(klass_RInfo); // object klass or other subclass
939 // __ push(sup_k_RInfo); // array element klass or other superclass
940 // __ bl(slow_subtype_check);
941 // Note that the subclass is pushed first, and is therefore deepest.
942 enum layout {
943 r0_off, r0_off_hi,
944 r2_off, r2_off_hi,
945 r4_off, r4_off_hi,
946 r5_off, r5_off_hi,
947 sup_k_off, sup_k_off_hi,
948 klass_off, klass_off_hi,
949 framesize,
950 result_off = sup_k_off
951 };
952
953 __ set_info("slow_subtype_check", dont_gc_arguments);
954 __ push(RegSet::of(r0, r2, r4, r5), sp);
1106 break;
1107
1108 case predicate_failed_trap_id:
1109 {
1110 StubFrame f(sasm, "predicate_failed_trap", dont_gc_arguments);
1111
1112 OopMap* map = save_live_registers(sasm);
1113
1114 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, predicate_failed_trap));
1115 oop_maps = new OopMapSet();
1116 oop_maps->add_gc_map(call_offset, map);
1117 restore_live_registers(sasm);
1118 __ leave();
1119 DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
1120 assert(deopt_blob != NULL, "deoptimization blob must have been created");
1121
1122 __ far_jump(RuntimeAddress(deopt_blob->unpack_with_reexecution()));
1123 }
1124 break;
1125
1126
1127 default:
1128 { StubFrame f(sasm, "unimplemented entry", dont_gc_arguments);
1129 __ mov(r0, (int)id);
1130 __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), r0);
1131 __ should_not_reach_here();
1132 }
1133 break;
1134 }
1135 }
1136 return oop_maps;
1137 }
1138
1139 #undef __
1140
1141 const char *Runtime1::pd_name_for_address(address entry) { Unimplemented(); return 0; }
|
756 case counter_overflow_id:
757 {
758 Register bci = r0, method = r1;
759 __ enter();
760 OopMap* map = save_live_registers(sasm);
761 // Retrieve bci
762 __ ldrw(bci, Address(rfp, 2*BytesPerWord));
763 // And a pointer to the Method*
764 __ ldr(method, Address(rfp, 3*BytesPerWord));
765 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci, method);
766 oop_maps = new OopMapSet();
767 oop_maps->add_gc_map(call_offset, map);
768 restore_live_registers(sasm);
769 __ leave();
770 __ ret(lr);
771 }
772 break;
773
774 case new_type_array_id:
775 case new_object_array_id:
776 case new_value_array_id:
777 {
778 Register length = r19; // Incoming
779 Register klass = r3; // Incoming
780 Register obj = r0; // Result
781
782 if (id == new_type_array_id) {
783 __ set_info("new_type_array", dont_gc_arguments);
784 }
785 else if (id == new_object_array_id) {
786 __ set_info("new_object_array", dont_gc_arguments);
787 }
788 else {
789 __ set_info("new_value_array", dont_gc_arguments);
790 }
791
792 #ifdef ASSERT
793 // assert object type is really an array of the proper kind
794 {
795 Label ok;
796 Register t0 = obj;
797 __ ldrw(t0, Address(klass, Klass::layout_helper_offset()));
798 __ asrw(t0, t0, Klass::_lh_array_tag_shift);
799
800 int tag = 0;
801 switch (id) {
802 case new_type_array_id: tag = Klass::_lh_array_tag_type_value; break;
803 case new_object_array_id: tag = Klass::_lh_array_tag_obj_value; break;
804 case new_value_array_id: tag = Klass::_lh_array_tag_vt_value; break;
805 default: ShouldNotReachHere();
806 }
807 __ mov(rscratch1, tag);
808 __ cmpw(t0, rscratch1);
809 __ br(Assembler::EQ, ok);
810 __ stop("assert(is an array klass)");
811 __ should_not_reach_here();
812 __ bind(ok);
813 }
814 #endif // ASSERT
815
816 // If TLAB is disabled, see if there is support for inlining contiguous
817 // allocations.
818 // Otherwise, just go to the slow path.
819 if (!UseTLAB && Universe::heap()->supports_inline_contig_alloc()) {
820 Register arr_size = r4;
821 Register t1 = r2;
822 Register t2 = r5;
823 Label slow_path;
824 assert_different_registers(length, klass, obj, arr_size, t1, t2);
825
826 // check that array length is small enough for fast path.
846 __ ldrb(t1, Address(klass, in_bytes(Klass::layout_helper_offset()) + (Klass::_lh_header_size_shift / BitsPerByte)));
847 assert(Klass::_lh_header_size_shift % BitsPerByte == 0, "bytewise");
848 assert(Klass::_lh_header_size_mask <= 0xFF, "bytewise");
849 __ andr(t1, t1, Klass::_lh_header_size_mask);
850 __ sub(arr_size, arr_size, t1); // body length
851 __ add(t1, t1, obj); // body start
852 __ initialize_body(t1, arr_size, 0, t2);
853 __ verify_oop(obj);
854
855 __ ret(lr);
856
857 __ bind(slow_path);
858 }
859
860 __ enter();
861 OopMap* map = save_live_registers(sasm);
862 int call_offset;
863 if (id == new_type_array_id) {
864 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_type_array), klass, length);
865 } else {
866 // Runtime1::new_object_array handles both object and value arrays
867 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_object_array), klass, length);
868 }
869
870 oop_maps = new OopMapSet();
871 oop_maps->add_gc_map(call_offset, map);
872 restore_live_registers_except_r0(sasm);
873
874 __ verify_oop(obj);
875 __ leave();
876 __ ret(lr);
877
878 // r0: new array
879 }
880 break;
881
882 case new_multi_array_id:
883 { StubFrame f(sasm, "new_multi_array", dont_gc_arguments);
884 // r0,: klass
885 // r19,: rank
886 // r2: address of 1st dimension
887 OopMap* map = save_live_registers(sasm);
888 __ mov(c_rarg1, r0);
889 __ mov(c_rarg3, r2);
890 __ mov(c_rarg2, r19);
891 int call_offset = __ call_RT(r0, noreg, CAST_FROM_FN_PTR(address, new_multi_array), r1, r2, r3);
892
893 oop_maps = new OopMapSet();
894 oop_maps->add_gc_map(call_offset, map);
895 restore_live_registers_except_r0(sasm);
896
897 // r0,: new multi array
898 __ verify_oop(r0);
899 }
900 break;
901
902 case buffer_value_args_id:
903 case buffer_value_args_no_receiver_id:
904 {
905 const char* name = (id == buffer_value_args_id) ?
906 "buffer_value_args" : "buffer_value_args_no_receiver";
907 StubFrame f(sasm, name, dont_gc_arguments);
908 OopMap* map = save_live_registers(sasm, 2);
909 Register method = r1;
910 address entry = (id == buffer_value_args_id) ?
911 CAST_FROM_FN_PTR(address, buffer_value_args) :
912 CAST_FROM_FN_PTR(address, buffer_value_args_no_receiver);
913 int call_offset = __ call_RT(r0, noreg, entry, method);
914 oop_maps = new OopMapSet();
915 oop_maps->add_gc_map(call_offset, map);
916 restore_live_registers_except_r0(sasm);
917 __ verify_oop(r0); // r0: an array of buffered value objects
918 }
919 break;
920
921 case load_flattened_array_id:
922 {
923 StubFrame f(sasm, "load_flattened_array", dont_gc_arguments);
924 OopMap* map = save_live_registers(sasm, 3);
925
926 // Called with store_parameter and not C abi
927
928 f.load_argument(1, r0); // r0,: array
929 f.load_argument(0, r1); // r1,: index
930 int call_offset = __ call_RT(r0, noreg, CAST_FROM_FN_PTR(address, load_flattened_array), r0, r1);
931
932 oop_maps = new OopMapSet();
933 oop_maps->add_gc_map(call_offset, map);
934 restore_live_registers_except_r0(sasm);
935
936 // r0: loaded element at array[index]
937 __ verify_oop(r0);
938 }
939 break;
940
941 case store_flattened_array_id:
942 {
943 StubFrame f(sasm, "store_flattened_array", dont_gc_arguments);
944 OopMap* map = save_live_registers(sasm, 4);
945
946 // Called with store_parameter and not C abi
947
948 f.load_argument(2, r0); // r0: array
949 f.load_argument(1, r1); // r1: index
950 f.load_argument(0, r2); // r2: value
951 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, store_flattened_array), r0, r1, r2);
952
953 oop_maps = new OopMapSet();
954 oop_maps->add_gc_map(call_offset, map);
955 restore_live_registers_except_r0(sasm);
956 }
957 break;
958
959 case substitutability_check_id:
960 {
961 StubFrame f(sasm, "substitutability_check", dont_gc_arguments);
962 OopMap* map = save_live_registers(sasm, 3);
963
964 // Called with store_parameter and not C abi
965
966 f.load_argument(1, r0); // r0,: left
967 f.load_argument(0, r1); // r1,: right
968 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, substitutability_check), r0, r1);
969
970 oop_maps = new OopMapSet();
971 oop_maps->add_gc_map(call_offset, map);
972 restore_live_registers_except_r0(sasm);
973
974 // r0,: are the two operands substitutable
975 }
976 break;
977
978
979
980 case register_finalizer_id:
981 {
982 __ set_info("register_finalizer", dont_gc_arguments);
983
984 // This is called via call_runtime so the arguments
985 // will be place in C abi locations
986
987 __ verify_oop(c_rarg0);
988
989 // load the klass and check the has finalizer flag
990 Label register_finalizer;
991 Register t = r5;
992 __ load_klass(t, r0);
993 __ ldrw(t, Address(t, Klass::access_flags_offset()));
994 __ tbnz(t, exact_log2(JVM_ACC_HAS_FINALIZER), register_finalizer);
995 __ ret(lr);
996
997 __ bind(register_finalizer);
998 __ enter();
999 OopMap* oop_map = save_live_registers(sasm);
1000 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, SharedRuntime::register_finalizer), r0);
1001 oop_maps = new OopMapSet();
1002 oop_maps->add_gc_map(call_offset, oop_map);
1003
1004 // Now restore all the live registers
1005 restore_live_registers(sasm);
1006
1007 __ leave();
1008 __ ret(lr);
1009 }
1010 break;
1011
1012 case throw_class_cast_exception_id:
1013 { StubFrame f(sasm, "throw_class_cast_exception", dont_gc_arguments);
1014 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_class_cast_exception), true);
1015 }
1016 break;
1017
1018 case throw_incompatible_class_change_error_id:
1019 { StubFrame f(sasm, "throw_incompatible_class_change_exception", dont_gc_arguments);
1020 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false);
1021 }
1022 break;
1023
1024 case throw_illegal_monitor_state_exception_id:
1025 { StubFrame f(sasm, "throw_illegal_monitor_state_exception", dont_gc_arguments);
1026 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_illegal_monitor_state_exception), false);
1027 }
1028 break;
1029
1030 case slow_subtype_check_id:
1031 {
1032 // Typical calling sequence:
1033 // __ push(klass_RInfo); // object klass or other subclass
1034 // __ push(sup_k_RInfo); // array element klass or other superclass
1035 // __ bl(slow_subtype_check);
1036 // Note that the subclass is pushed first, and is therefore deepest.
1037 enum layout {
1038 r0_off, r0_off_hi,
1039 r2_off, r2_off_hi,
1040 r4_off, r4_off_hi,
1041 r5_off, r5_off_hi,
1042 sup_k_off, sup_k_off_hi,
1043 klass_off, klass_off_hi,
1044 framesize,
1045 result_off = sup_k_off
1046 };
1047
1048 __ set_info("slow_subtype_check", dont_gc_arguments);
1049 __ push(RegSet::of(r0, r2, r4, r5), sp);
1201 break;
1202
1203 case predicate_failed_trap_id:
1204 {
1205 StubFrame f(sasm, "predicate_failed_trap", dont_gc_arguments);
1206
1207 OopMap* map = save_live_registers(sasm);
1208
1209 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, predicate_failed_trap));
1210 oop_maps = new OopMapSet();
1211 oop_maps->add_gc_map(call_offset, map);
1212 restore_live_registers(sasm);
1213 __ leave();
1214 DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
1215 assert(deopt_blob != NULL, "deoptimization blob must have been created");
1216
1217 __ far_jump(RuntimeAddress(deopt_blob->unpack_with_reexecution()));
1218 }
1219 break;
1220
1221 default:
1222 // DMS CHECK: This code should be fixed in JDK workspace, because it fails
1223 // with assert during vm intialization rather than insert a call
1224 // to unimplemented_entry
1225 { StubFrame f(sasm, "unimplemented entry", dont_gc_arguments);
1226 __ mov(r0, (int)id);
1227 __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), r0);
1228 __ should_not_reach_here();
1229 }
1230 break;
1231 }
1232 }
1233
1234
1235 return oop_maps;
1236 }
1237
1238 #undef __
1239
1240 const char *Runtime1::pd_name_for_address(address entry) { Unimplemented(); return 0; }
|