832 break;
833
834 case C1StubId::new_instance_id:
835 case C1StubId::fast_new_instance_id:
836 case C1StubId::fast_new_instance_init_check_id:
837 {
838 Register klass = rdx; // Incoming
839 Register obj = rax; // Result
840
841 if (id == C1StubId::new_instance_id) {
842 __ set_info("new_instance", dont_gc_arguments);
843 } else if (id == C1StubId::fast_new_instance_id) {
844 __ set_info("fast new_instance", dont_gc_arguments);
845 } else {
846 assert(id == C1StubId::fast_new_instance_init_check_id, "bad C1StubId");
847 __ set_info("fast new_instance init check", dont_gc_arguments);
848 }
849
850 __ enter();
851 OopMap* map = save_live_registers(sasm, 2);
852 int call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_instance), klass);
853 oop_maps = new OopMapSet();
854 oop_maps->add_gc_map(call_offset, map);
855 restore_live_registers_except_rax(sasm);
856 __ verify_oop(obj);
857 __ leave();
858 __ ret(0);
859
860 // rax,: new instance
861 }
862
863 break;
864
865 case C1StubId::counter_overflow_id:
866 {
867 Register bci = rax, method = rbx;
868 __ enter();
869 OopMap* map = save_live_registers(sasm, 3);
870 // Retrieve bci
871 __ movl(bci, Address(rbp, 2*BytesPerWord));
872 // And a pointer to the Method*
873 __ movptr(method, Address(rbp, 3*BytesPerWord));
874 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci, method);
875 oop_maps = new OopMapSet();
876 oop_maps->add_gc_map(call_offset, map);
877 restore_live_registers(sasm);
878 __ leave();
879 __ ret(0);
880 }
881 break;
882
883 case C1StubId::new_type_array_id:
884 case C1StubId::new_object_array_id:
885 {
886 Register length = rbx; // Incoming
887 Register klass = rdx; // Incoming
888 Register obj = rax; // Result
889
890 if (id == C1StubId::new_type_array_id) {
891 __ set_info("new_type_array", dont_gc_arguments);
892 } else {
893 __ set_info("new_object_array", dont_gc_arguments);
894 }
895
896 #ifdef ASSERT
897 // assert object type is really an array of the proper kind
898 {
899 Label ok;
900 Register t0 = obj;
901 __ movl(t0, Address(klass, Klass::layout_helper_offset()));
902 __ sarl(t0, Klass::_lh_array_tag_shift);
903 int tag = ((id == C1StubId::new_type_array_id)
904 ? Klass::_lh_array_tag_type_value
905 : Klass::_lh_array_tag_obj_value);
906 __ cmpl(t0, tag);
907 __ jcc(Assembler::equal, ok);
908 __ stop("assert(is an array klass)");
909 __ should_not_reach_here();
910 __ bind(ok);
911 }
912 #endif // ASSERT
913
914 __ enter();
915 OopMap* map = save_live_registers(sasm, 3);
916 int call_offset;
917 if (id == C1StubId::new_type_array_id) {
918 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_type_array), klass, length);
919 } else {
920 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_object_array), klass, length);
921 }
922
923 oop_maps = new OopMapSet();
924 oop_maps->add_gc_map(call_offset, map);
925 restore_live_registers_except_rax(sasm);
926
927 __ verify_oop(obj);
928 __ leave();
929 __ ret(0);
930
931 // rax,: new array
932 }
933 break;
934
935 case C1StubId::new_multi_array_id:
936 { StubFrame f(sasm, "new_multi_array", dont_gc_arguments);
937 // rax,: klass
938 // rbx,: rank
939 // rcx: address of 1st dimension
940 OopMap* map = save_live_registers(sasm, 4);
941 int call_offset = __ call_RT(rax, noreg, CAST_FROM_FN_PTR(address, new_multi_array), rax, rbx, rcx);
942
943 oop_maps = new OopMapSet();
944 oop_maps->add_gc_map(call_offset, map);
945 restore_live_registers_except_rax(sasm);
946
947 // rax,: new multi array
948 __ verify_oop(rax);
949 }
950 break;
951
952 case C1StubId::register_finalizer_id:
953 {
954 __ set_info("register_finalizer", dont_gc_arguments);
955
956 // This is called via call_runtime so the arguments
957 // will be place in C abi locations
958
959 __ verify_oop(c_rarg0);
960 __ mov(rax, c_rarg0);
961
962 // load the klass and check the has finalizer flag
963 Label register_finalizer;
964 Register t = rsi;
965 __ load_klass(t, rax, rscratch1);
966 __ testb(Address(t, Klass::misc_flags_offset()), KlassFlags::_misc_has_finalizer);
967 __ jcc(Assembler::notZero, register_finalizer);
968 __ ret(0);
969
970 __ bind(register_finalizer);
971 __ enter();
1025 // activation and we are calling a leaf VM function only.
1026 generate_unwind_exception(sasm);
1027 }
1028 break;
1029
1030 case C1StubId::throw_array_store_exception_id:
1031 { StubFrame f(sasm, "throw_array_store_exception", dont_gc_arguments);
1032 // tos + 0: link
1033 // + 1: return address
1034 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_array_store_exception), true);
1035 }
1036 break;
1037
1038 case C1StubId::throw_class_cast_exception_id:
1039 { StubFrame f(sasm, "throw_class_cast_exception", dont_gc_arguments);
1040 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_class_cast_exception), true);
1041 }
1042 break;
1043
1044 case C1StubId::throw_incompatible_class_change_error_id:
1045 { StubFrame f(sasm, "throw_incompatible_class_cast_exception", dont_gc_arguments);
1046 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false);
1047 }
1048 break;
1049
1050 case C1StubId::slow_subtype_check_id:
1051 {
1052 // Typical calling sequence:
1053 // __ push(klass_RInfo); // object klass or other subclass
1054 // __ push(sup_k_RInfo); // array element klass or other superclass
1055 // __ call(slow_subtype_check);
1056 // Note that the subclass is pushed first, and is therefore deepest.
1057 // Previous versions of this code reversed the names 'sub' and 'super'.
1058 // This was operationally harmless but made the code unreadable.
1059 enum layout {
1060 rax_off, SLOT2(raxH_off)
1061 rcx_off, SLOT2(rcxH_off)
1062 rsi_off, SLOT2(rsiH_off)
1063 rdi_off, SLOT2(rdiH_off)
1064 // saved_rbp_off, SLOT2(saved_rbpH_off)
1065 return_off, SLOT2(returnH_off)
1066 sup_k_off, SLOT2(sup_kH_off)
1067 klass_off, SLOT2(superH_off)
1068 framesize,
|
832 break;
833
834 case C1StubId::new_instance_id:
835 case C1StubId::fast_new_instance_id:
836 case C1StubId::fast_new_instance_init_check_id:
837 {
838 Register klass = rdx; // Incoming
839 Register obj = rax; // Result
840
841 if (id == C1StubId::new_instance_id) {
842 __ set_info("new_instance", dont_gc_arguments);
843 } else if (id == C1StubId::fast_new_instance_id) {
844 __ set_info("fast new_instance", dont_gc_arguments);
845 } else {
846 assert(id == C1StubId::fast_new_instance_init_check_id, "bad C1StubId");
847 __ set_info("fast new_instance init check", dont_gc_arguments);
848 }
849
850 __ enter();
851 OopMap* map = save_live_registers(sasm, 2);
852 int call_offset;
853 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_instance), klass);
854 oop_maps = new OopMapSet();
855 oop_maps->add_gc_map(call_offset, map);
856 restore_live_registers_except_rax(sasm);
857 __ verify_oop(obj);
858 __ leave();
859 __ ret(0);
860
861 // rax,: new instance
862 }
863
864 break;
865
866 case C1StubId::counter_overflow_id:
867 {
868 Register bci = rax, method = rbx;
869 __ enter();
870 OopMap* map = save_live_registers(sasm, 3);
871 // Retrieve bci
872 __ movl(bci, Address(rbp, 2*BytesPerWord));
873 // And a pointer to the Method*
874 __ movptr(method, Address(rbp, 3*BytesPerWord));
875 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci, method);
876 oop_maps = new OopMapSet();
877 oop_maps->add_gc_map(call_offset, map);
878 restore_live_registers(sasm);
879 __ leave();
880 __ ret(0);
881 }
882 break;
883
884 case C1StubId::new_type_array_id:
885 case C1StubId::new_object_array_id:
886 case C1StubId::new_null_free_array_id:
887 {
888 Register length = rbx; // Incoming
889 Register klass = rdx; // Incoming
890 Register obj = rax; // Result
891
892 if (id == C1StubId::new_type_array_id) {
893 __ set_info("new_type_array", dont_gc_arguments);
894 } else if (id == C1StubId::new_object_array_id) {
895 __ set_info("new_object_array", dont_gc_arguments);
896 } else {
897 __ set_info("new_null_free_array", dont_gc_arguments);
898 }
899
900 #ifdef ASSERT
901 // assert object type is really an array of the proper kind
902 {
903 Label ok;
904 Register t0 = obj;
905 __ movl(t0, Address(klass, Klass::layout_helper_offset()));
906 __ sarl(t0, Klass::_lh_array_tag_shift);
907 switch (id) {
908 case C1StubId::new_type_array_id:
909 __ cmpl(t0, Klass::_lh_array_tag_type_value);
910 __ jcc(Assembler::equal, ok);
911 __ stop("assert(is a type array klass)");
912 break;
913 case C1StubId::new_object_array_id:
914 __ cmpl(t0, Klass::_lh_array_tag_obj_value); // new "[Ljava/lang/Object;"
915 __ jcc(Assembler::equal, ok);
916 __ cmpl(t0, Klass::_lh_array_tag_vt_value); // new "[LVT;"
917 __ jcc(Assembler::equal, ok);
918 __ stop("assert(is an object or inline type array klass)");
919 break;
920 case C1StubId::new_null_free_array_id:
921 __ cmpl(t0, Klass::_lh_array_tag_vt_value); // the array can be a flat array.
922 __ jcc(Assembler::equal, ok);
923 __ cmpl(t0, Klass::_lh_array_tag_obj_value); // the array cannot be a flat array (due to InlineArrayElementMaxFlatSize, etc)
924 __ jcc(Assembler::equal, ok);
925 __ stop("assert(is an object or inline type array klass)");
926 break;
927 default: ShouldNotReachHere();
928 }
929 __ should_not_reach_here();
930 __ bind(ok);
931 }
932 #endif // ASSERT
933
934 __ enter();
935 OopMap* map = save_live_registers(sasm, 3);
936 int call_offset;
937 if (id == C1StubId::new_type_array_id) {
938 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_type_array), klass, length);
939 } else if (id == C1StubId::new_object_array_id) {
940 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_object_array), klass, length);
941 } else {
942 assert(id == C1StubId::new_null_free_array_id, "must be");
943 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_null_free_array), klass, length);
944 }
945
946 oop_maps = new OopMapSet();
947 oop_maps->add_gc_map(call_offset, map);
948 restore_live_registers_except_rax(sasm);
949
950 __ verify_oop(obj);
951 __ leave();
952 __ ret(0);
953
954 // rax,: new array
955 }
956 break;
957
958 case C1StubId::new_multi_array_id:
959 { StubFrame f(sasm, "new_multi_array", dont_gc_arguments);
960 // rax,: klass
961 // rbx,: rank
962 // rcx: address of 1st dimension
963 OopMap* map = save_live_registers(sasm, 4);
964 int call_offset = __ call_RT(rax, noreg, CAST_FROM_FN_PTR(address, new_multi_array), rax, rbx, rcx);
965
966 oop_maps = new OopMapSet();
967 oop_maps->add_gc_map(call_offset, map);
968 restore_live_registers_except_rax(sasm);
969
970 // rax,: new multi array
971 __ verify_oop(rax);
972 }
973 break;
974
975 case C1StubId::load_flat_array_id:
976 {
977 StubFrame f(sasm, "load_flat_array", dont_gc_arguments);
978 OopMap* map = save_live_registers(sasm, 3);
979
980 // Called with store_parameter and not C abi
981
982 f.load_argument(1, rax); // rax,: array
983 f.load_argument(0, rbx); // rbx,: index
984 int call_offset = __ call_RT(rax, noreg, CAST_FROM_FN_PTR(address, load_flat_array), rax, rbx);
985
986 oop_maps = new OopMapSet();
987 oop_maps->add_gc_map(call_offset, map);
988 restore_live_registers_except_rax(sasm);
989
990 // rax,: loaded element at array[index]
991 __ verify_oop(rax);
992 }
993 break;
994
995 case C1StubId::store_flat_array_id:
996 {
997 StubFrame f(sasm, "store_flat_array", dont_gc_arguments);
998 OopMap* map = save_live_registers(sasm, 4);
999
1000 // Called with store_parameter and not C abi
1001
1002 f.load_argument(2, rax); // rax,: array
1003 f.load_argument(1, rbx); // rbx,: index
1004 f.load_argument(0, rcx); // rcx,: value
1005 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, store_flat_array), rax, rbx, rcx);
1006
1007 oop_maps = new OopMapSet();
1008 oop_maps->add_gc_map(call_offset, map);
1009 restore_live_registers_except_rax(sasm);
1010 }
1011 break;
1012
1013 case C1StubId::substitutability_check_id:
1014 {
1015 StubFrame f(sasm, "substitutability_check", dont_gc_arguments);
1016 OopMap* map = save_live_registers(sasm, 3);
1017
1018 // Called with store_parameter and not C abi
1019
1020 f.load_argument(1, rax); // rax,: left
1021 f.load_argument(0, rbx); // rbx,: right
1022 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, substitutability_check), rax, rbx);
1023
1024 oop_maps = new OopMapSet();
1025 oop_maps->add_gc_map(call_offset, map);
1026 restore_live_registers_except_rax(sasm);
1027
1028 // rax,: are the two operands substitutable
1029 }
1030 break;
1031
1032
1033 case C1StubId::buffer_inline_args_id:
1034 case C1StubId::buffer_inline_args_no_receiver_id:
1035 {
1036 const char* name = (id == C1StubId::buffer_inline_args_id) ?
1037 "buffer_inline_args" : "buffer_inline_args_no_receiver";
1038 StubFrame f(sasm, name, dont_gc_arguments);
1039 OopMap* map = save_live_registers(sasm, 2);
1040 Register method = rbx;
1041 address entry = (id == C1StubId::buffer_inline_args_id) ?
1042 CAST_FROM_FN_PTR(address, buffer_inline_args) :
1043 CAST_FROM_FN_PTR(address, buffer_inline_args_no_receiver);
1044 int call_offset = __ call_RT(rax, noreg, entry, method);
1045 oop_maps = new OopMapSet();
1046 oop_maps->add_gc_map(call_offset, map);
1047 restore_live_registers_except_rax(sasm);
1048 __ verify_oop(rax); // rax: an array of buffered value objects
1049 }
1050 break;
1051
1052 case C1StubId::register_finalizer_id:
1053 {
1054 __ set_info("register_finalizer", dont_gc_arguments);
1055
1056 // This is called via call_runtime so the arguments
1057 // will be place in C abi locations
1058
1059 __ verify_oop(c_rarg0);
1060 __ mov(rax, c_rarg0);
1061
1062 // load the klass and check the has finalizer flag
1063 Label register_finalizer;
1064 Register t = rsi;
1065 __ load_klass(t, rax, rscratch1);
1066 __ testb(Address(t, Klass::misc_flags_offset()), KlassFlags::_misc_has_finalizer);
1067 __ jcc(Assembler::notZero, register_finalizer);
1068 __ ret(0);
1069
1070 __ bind(register_finalizer);
1071 __ enter();
1125 // activation and we are calling a leaf VM function only.
1126 generate_unwind_exception(sasm);
1127 }
1128 break;
1129
1130 case C1StubId::throw_array_store_exception_id:
1131 { StubFrame f(sasm, "throw_array_store_exception", dont_gc_arguments);
1132 // tos + 0: link
1133 // + 1: return address
1134 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_array_store_exception), true);
1135 }
1136 break;
1137
1138 case C1StubId::throw_class_cast_exception_id:
1139 { StubFrame f(sasm, "throw_class_cast_exception", dont_gc_arguments);
1140 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_class_cast_exception), true);
1141 }
1142 break;
1143
1144 case C1StubId::throw_incompatible_class_change_error_id:
1145 { StubFrame f(sasm, "throw_incompatible_class_change_error", dont_gc_arguments);
1146 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false);
1147 }
1148 break;
1149
1150 case C1StubId::throw_illegal_monitor_state_exception_id:
1151 { StubFrame f(sasm, "throw_illegal_monitor_state_exception", dont_gc_arguments);
1152 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_illegal_monitor_state_exception), false);
1153 }
1154 break;
1155
1156 case C1StubId::throw_identity_exception_id:
1157 { StubFrame f(sasm, "throw_identity_exception", dont_gc_arguments);
1158 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_identity_exception), true);
1159 }
1160 break;
1161
1162 case C1StubId::slow_subtype_check_id:
1163 {
1164 // Typical calling sequence:
1165 // __ push(klass_RInfo); // object klass or other subclass
1166 // __ push(sup_k_RInfo); // array element klass or other superclass
1167 // __ call(slow_subtype_check);
1168 // Note that the subclass is pushed first, and is therefore deepest.
1169 // Previous versions of this code reversed the names 'sub' and 'super'.
1170 // This was operationally harmless but made the code unreadable.
1171 enum layout {
1172 rax_off, SLOT2(raxH_off)
1173 rcx_off, SLOT2(rcxH_off)
1174 rsi_off, SLOT2(rsiH_off)
1175 rdi_off, SLOT2(rdiH_off)
1176 // saved_rbp_off, SLOT2(saved_rbpH_off)
1177 return_off, SLOT2(returnH_off)
1178 sup_k_off, SLOT2(sup_kH_off)
1179 klass_off, SLOT2(superH_off)
1180 framesize,
|