1018 break;
1019
1020 case new_instance_id:
1021 case fast_new_instance_id:
1022 case fast_new_instance_init_check_id:
1023 {
1024 Register klass = rdx; // Incoming
1025 Register obj = rax; // Result
1026
1027 if (id == new_instance_id) {
1028 __ set_info("new_instance", dont_gc_arguments);
1029 } else if (id == fast_new_instance_id) {
1030 __ set_info("fast new_instance", dont_gc_arguments);
1031 } else {
1032 assert(id == fast_new_instance_init_check_id, "bad StubID");
1033 __ set_info("fast new_instance init check", dont_gc_arguments);
1034 }
1035
1036 __ enter();
1037 OopMap* map = save_live_registers(sasm, 2);
1038 int call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_instance), klass);
1039 oop_maps = new OopMapSet();
1040 oop_maps->add_gc_map(call_offset, map);
1041 restore_live_registers_except_rax(sasm);
1042 __ verify_oop(obj);
1043 __ leave();
1044 __ ret(0);
1045
1046 // rax,: new instance
1047 }
1048
1049 break;
1050
1051 case counter_overflow_id:
1052 {
1053 Register bci = rax, method = rbx;
1054 __ enter();
1055 OopMap* map = save_live_registers(sasm, 3);
1056 // Retrieve bci
1057 __ movl(bci, Address(rbp, 2*BytesPerWord));
1058 // And a pointer to the Method*
1059 __ movptr(method, Address(rbp, 3*BytesPerWord));
1060 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci, method);
1061 oop_maps = new OopMapSet();
1062 oop_maps->add_gc_map(call_offset, map);
1063 restore_live_registers(sasm);
1064 __ leave();
1065 __ ret(0);
1066 }
1067 break;
1068
1069 case new_type_array_id:
1070 case new_object_array_id:
1071 {
1072 Register length = rbx; // Incoming
1073 Register klass = rdx; // Incoming
1074 Register obj = rax; // Result
1075
1076 if (id == new_type_array_id) {
1077 __ set_info("new_type_array", dont_gc_arguments);
1078 } else {
1079 __ set_info("new_object_array", dont_gc_arguments);
1080 }
1081
1082 #ifdef ASSERT
1083 // assert object type is really an array of the proper kind
1084 {
1085 Label ok;
1086 Register t0 = obj;
1087 __ movl(t0, Address(klass, Klass::layout_helper_offset()));
1088 __ sarl(t0, Klass::_lh_array_tag_shift);
1089 int tag = ((id == new_type_array_id)
1090 ? Klass::_lh_array_tag_type_value
1091 : Klass::_lh_array_tag_obj_value);
1092 __ cmpl(t0, tag);
1093 __ jcc(Assembler::equal, ok);
1094 __ stop("assert(is an array klass)");
1095 __ should_not_reach_here();
1096 __ bind(ok);
1097 }
1098 #endif // ASSERT
1099
1100 __ enter();
1101 OopMap* map = save_live_registers(sasm, 3);
1102 int call_offset;
1103 if (id == new_type_array_id) {
1104 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_type_array), klass, length);
1105 } else {
1106 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_object_array), klass, length);
1107 }
1108
1109 oop_maps = new OopMapSet();
1110 oop_maps->add_gc_map(call_offset, map);
1111 restore_live_registers_except_rax(sasm);
1112
1113 __ verify_oop(obj);
1114 __ leave();
1115 __ ret(0);
1116
1117 // rax,: new array
1118 }
1119 break;
1120
1121 case new_multi_array_id:
1122 { StubFrame f(sasm, "new_multi_array", dont_gc_arguments);
1123 // rax,: klass
1124 // rbx,: rank
1125 // rcx: address of 1st dimension
1126 OopMap* map = save_live_registers(sasm, 4);
1127 int call_offset = __ call_RT(rax, noreg, CAST_FROM_FN_PTR(address, new_multi_array), rax, rbx, rcx);
1128
1129 oop_maps = new OopMapSet();
1130 oop_maps->add_gc_map(call_offset, map);
1131 restore_live_registers_except_rax(sasm);
1132
1133 // rax,: new multi array
1134 __ verify_oop(rax);
1135 }
1136 break;
1137
1138 case register_finalizer_id:
1139 {
1140 __ set_info("register_finalizer", dont_gc_arguments);
1141
1142 // This is called via call_runtime so the arguments
1143 // will be place in C abi locations
1144
1145 #ifdef _LP64
1146 __ verify_oop(c_rarg0);
1147 __ mov(rax, c_rarg0);
1148 #else
1149 // The object is passed on the stack and we haven't pushed a
1150 // frame yet so it's one work away from top of stack.
1151 __ movptr(rax, Address(rsp, 1 * BytesPerWord));
1152 __ verify_oop(rax);
1153 #endif // _LP64
1154
1155 // load the klass and check the has finalizer flag
1156 Label register_finalizer;
1157 Register t = rsi;
1219 // activation and we are calling a leaf VM function only.
1220 generate_unwind_exception(sasm);
1221 }
1222 break;
1223
1224 case throw_array_store_exception_id:
1225 { StubFrame f(sasm, "throw_array_store_exception", dont_gc_arguments);
1226 // tos + 0: link
1227 // + 1: return address
1228 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_array_store_exception), true);
1229 }
1230 break;
1231
1232 case throw_class_cast_exception_id:
1233 { StubFrame f(sasm, "throw_class_cast_exception", dont_gc_arguments);
1234 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_class_cast_exception), true);
1235 }
1236 break;
1237
1238 case throw_incompatible_class_change_error_id:
1239 { StubFrame f(sasm, "throw_incompatible_class_cast_exception", dont_gc_arguments);
1240 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false);
1241 }
1242 break;
1243
1244 case slow_subtype_check_id:
1245 {
1246 // Typical calling sequence:
1247 // __ push(klass_RInfo); // object klass or other subclass
1248 // __ push(sup_k_RInfo); // array element klass or other superclass
1249 // __ call(slow_subtype_check);
1250 // Note that the subclass is pushed first, and is therefore deepest.
1251 // Previous versions of this code reversed the names 'sub' and 'super'.
1252 // This was operationally harmless but made the code unreadable.
1253 enum layout {
1254 rax_off, SLOT2(raxH_off)
1255 rcx_off, SLOT2(rcxH_off)
1256 rsi_off, SLOT2(rsiH_off)
1257 rdi_off, SLOT2(rdiH_off)
1258 // saved_rbp_off, SLOT2(saved_rbpH_off)
1259 return_off, SLOT2(returnH_off)
1260 sup_k_off, SLOT2(sup_kH_off)
1261 klass_off, SLOT2(superH_off)
1262 framesize,
1263 result_off = klass_off // deepest argument is also the return value
|
1018 break;
1019
1020 case new_instance_id:
1021 case fast_new_instance_id:
1022 case fast_new_instance_init_check_id:
1023 {
1024 Register klass = rdx; // Incoming
1025 Register obj = rax; // Result
1026
1027 if (id == new_instance_id) {
1028 __ set_info("new_instance", dont_gc_arguments);
1029 } else if (id == fast_new_instance_id) {
1030 __ set_info("fast new_instance", dont_gc_arguments);
1031 } else {
1032 assert(id == fast_new_instance_init_check_id, "bad StubID");
1033 __ set_info("fast new_instance init check", dont_gc_arguments);
1034 }
1035
1036 __ enter();
1037 OopMap* map = save_live_registers(sasm, 2);
1038 int call_offset;
1039 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_instance), klass);
1040 oop_maps = new OopMapSet();
1041 oop_maps->add_gc_map(call_offset, map);
1042 restore_live_registers_except_rax(sasm);
1043 __ verify_oop(obj);
1044 __ leave();
1045 __ ret(0);
1046
1047 // rax,: new instance
1048 }
1049
1050 break;
1051
1052 case counter_overflow_id:
1053 {
1054 Register bci = rax, method = rbx;
1055 __ enter();
1056 OopMap* map = save_live_registers(sasm, 3);
1057 // Retrieve bci
1058 __ movl(bci, Address(rbp, 2*BytesPerWord));
1059 // And a pointer to the Method*
1060 __ movptr(method, Address(rbp, 3*BytesPerWord));
1061 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci, method);
1062 oop_maps = new OopMapSet();
1063 oop_maps->add_gc_map(call_offset, map);
1064 restore_live_registers(sasm);
1065 __ leave();
1066 __ ret(0);
1067 }
1068 break;
1069
1070 case new_type_array_id:
1071 case new_object_array_id:
1072 case new_null_free_array_id:
1073 {
1074 Register length = rbx; // Incoming
1075 Register klass = rdx; // Incoming
1076 Register obj = rax; // Result
1077
1078 if (id == new_type_array_id) {
1079 __ set_info("new_type_array", dont_gc_arguments);
1080 } else if (id == new_object_array_id) {
1081 __ set_info("new_object_array", dont_gc_arguments);
1082 } else {
1083 __ set_info("new_null_free_array", dont_gc_arguments);
1084 }
1085
1086 #ifdef ASSERT
1087 // assert object type is really an array of the proper kind
1088 {
1089 Label ok;
1090 Register t0 = obj;
1091 __ movl(t0, Address(klass, Klass::layout_helper_offset()));
1092 __ sarl(t0, Klass::_lh_array_tag_shift);
1093 switch (id) {
1094 case new_type_array_id:
1095 __ cmpl(t0, Klass::_lh_array_tag_type_value);
1096 __ jcc(Assembler::equal, ok);
1097 __ stop("assert(is a type array klass)");
1098 break;
1099 case new_object_array_id:
1100 __ cmpl(t0, Klass::_lh_array_tag_obj_value); // new "[Ljava/lang/Object;"
1101 __ jcc(Assembler::equal, ok);
1102 __ cmpl(t0, Klass::_lh_array_tag_vt_value); // new "[LVT;"
1103 __ jcc(Assembler::equal, ok);
1104 __ stop("assert(is an object or inline type array klass)");
1105 break;
1106 case new_null_free_array_id:
1107 __ cmpl(t0, Klass::_lh_array_tag_vt_value); // the array can be a flat array.
1108 __ jcc(Assembler::equal, ok);
1109 __ cmpl(t0, Klass::_lh_array_tag_obj_value); // the array cannot be a flat array (due to InlineArrayElementMaxFlatSize, etc)
1110 __ jcc(Assembler::equal, ok);
1111 __ stop("assert(is an object or inline type array klass)");
1112 break;
1113 default: ShouldNotReachHere();
1114 }
1115 __ should_not_reach_here();
1116 __ bind(ok);
1117 }
1118 #endif // ASSERT
1119
1120 __ enter();
1121 OopMap* map = save_live_registers(sasm, 3);
1122 int call_offset;
1123 if (id == new_type_array_id) {
1124 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_type_array), klass, length);
1125 } else if (id == new_object_array_id) {
1126 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_object_array), klass, length);
1127 } else {
1128 assert(id == new_null_free_array_id, "must be");
1129 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_null_free_array), klass, length);
1130 }
1131
1132 oop_maps = new OopMapSet();
1133 oop_maps->add_gc_map(call_offset, map);
1134 restore_live_registers_except_rax(sasm);
1135
1136 __ verify_oop(obj);
1137 __ leave();
1138 __ ret(0);
1139
1140 // rax,: new array
1141 }
1142 break;
1143
1144 case new_multi_array_id:
1145 { StubFrame f(sasm, "new_multi_array", dont_gc_arguments);
1146 // rax,: klass
1147 // rbx,: rank
1148 // rcx: address of 1st dimension
1149 OopMap* map = save_live_registers(sasm, 4);
1150 int call_offset = __ call_RT(rax, noreg, CAST_FROM_FN_PTR(address, new_multi_array), rax, rbx, rcx);
1151
1152 oop_maps = new OopMapSet();
1153 oop_maps->add_gc_map(call_offset, map);
1154 restore_live_registers_except_rax(sasm);
1155
1156 // rax,: new multi array
1157 __ verify_oop(rax);
1158 }
1159 break;
1160
1161 case load_flat_array_id:
1162 {
1163 StubFrame f(sasm, "load_flat_array", dont_gc_arguments);
1164 OopMap* map = save_live_registers(sasm, 3);
1165
1166 // Called with store_parameter and not C abi
1167
1168 f.load_argument(1, rax); // rax,: array
1169 f.load_argument(0, rbx); // rbx,: index
1170 int call_offset = __ call_RT(rax, noreg, CAST_FROM_FN_PTR(address, load_flat_array), rax, rbx);
1171
1172 oop_maps = new OopMapSet();
1173 oop_maps->add_gc_map(call_offset, map);
1174 restore_live_registers_except_rax(sasm);
1175
1176 // rax,: loaded element at array[index]
1177 __ verify_oop(rax);
1178 }
1179 break;
1180
1181 case store_flat_array_id:
1182 {
1183 StubFrame f(sasm, "store_flat_array", dont_gc_arguments);
1184 OopMap* map = save_live_registers(sasm, 4);
1185
1186 // Called with store_parameter and not C abi
1187
1188 f.load_argument(2, rax); // rax,: array
1189 f.load_argument(1, rbx); // rbx,: index
1190 f.load_argument(0, rcx); // rcx,: value
1191 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, store_flat_array), rax, rbx, rcx);
1192
1193 oop_maps = new OopMapSet();
1194 oop_maps->add_gc_map(call_offset, map);
1195 restore_live_registers_except_rax(sasm);
1196 }
1197 break;
1198
1199 case substitutability_check_id:
1200 {
1201 StubFrame f(sasm, "substitutability_check", dont_gc_arguments);
1202 OopMap* map = save_live_registers(sasm, 3);
1203
1204 // Called with store_parameter and not C abi
1205
1206 f.load_argument(1, rax); // rax,: left
1207 f.load_argument(0, rbx); // rbx,: right
1208 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, substitutability_check), rax, rbx);
1209
1210 oop_maps = new OopMapSet();
1211 oop_maps->add_gc_map(call_offset, map);
1212 restore_live_registers_except_rax(sasm);
1213
1214 // rax,: are the two operands substitutable
1215 }
1216 break;
1217
1218
1219 case buffer_inline_args_id:
1220 case buffer_inline_args_no_receiver_id:
1221 {
1222 const char* name = (id == buffer_inline_args_id) ?
1223 "buffer_inline_args" : "buffer_inline_args_no_receiver";
1224 StubFrame f(sasm, name, dont_gc_arguments);
1225 OopMap* map = save_live_registers(sasm, 2);
1226 Register method = rbx;
1227 address entry = (id == buffer_inline_args_id) ?
1228 CAST_FROM_FN_PTR(address, buffer_inline_args) :
1229 CAST_FROM_FN_PTR(address, buffer_inline_args_no_receiver);
1230 int call_offset = __ call_RT(rax, noreg, entry, method);
1231 oop_maps = new OopMapSet();
1232 oop_maps->add_gc_map(call_offset, map);
1233 restore_live_registers_except_rax(sasm);
1234 __ verify_oop(rax); // rax: an array of buffered value objects
1235 }
1236 break;
1237
1238 case register_finalizer_id:
1239 {
1240 __ set_info("register_finalizer", dont_gc_arguments);
1241
1242 // This is called via call_runtime so the arguments
1243 // will be place in C abi locations
1244
1245 #ifdef _LP64
1246 __ verify_oop(c_rarg0);
1247 __ mov(rax, c_rarg0);
1248 #else
1249 // The object is passed on the stack and we haven't pushed a
1250 // frame yet so it's one work away from top of stack.
1251 __ movptr(rax, Address(rsp, 1 * BytesPerWord));
1252 __ verify_oop(rax);
1253 #endif // _LP64
1254
1255 // load the klass and check the has finalizer flag
1256 Label register_finalizer;
1257 Register t = rsi;
1319 // activation and we are calling a leaf VM function only.
1320 generate_unwind_exception(sasm);
1321 }
1322 break;
1323
1324 case throw_array_store_exception_id:
1325 { StubFrame f(sasm, "throw_array_store_exception", dont_gc_arguments);
1326 // tos + 0: link
1327 // + 1: return address
1328 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_array_store_exception), true);
1329 }
1330 break;
1331
1332 case throw_class_cast_exception_id:
1333 { StubFrame f(sasm, "throw_class_cast_exception", dont_gc_arguments);
1334 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_class_cast_exception), true);
1335 }
1336 break;
1337
1338 case throw_incompatible_class_change_error_id:
1339 { StubFrame f(sasm, "throw_incompatible_class_change_error", dont_gc_arguments);
1340 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false);
1341 }
1342 break;
1343
1344 case throw_illegal_monitor_state_exception_id:
1345 { StubFrame f(sasm, "throw_illegal_monitor_state_exception", dont_gc_arguments);
1346 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_illegal_monitor_state_exception), false);
1347 }
1348 break;
1349
1350 case throw_identity_exception_id:
1351 { StubFrame f(sasm, "throw_identity_exception", dont_gc_arguments);
1352 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_identity_exception), true);
1353 }
1354 break;
1355
1356 case slow_subtype_check_id:
1357 {
1358 // Typical calling sequence:
1359 // __ push(klass_RInfo); // object klass or other subclass
1360 // __ push(sup_k_RInfo); // array element klass or other superclass
1361 // __ call(slow_subtype_check);
1362 // Note that the subclass is pushed first, and is therefore deepest.
1363 // Previous versions of this code reversed the names 'sub' and 'super'.
1364 // This was operationally harmless but made the code unreadable.
1365 enum layout {
1366 rax_off, SLOT2(raxH_off)
1367 rcx_off, SLOT2(rcxH_off)
1368 rsi_off, SLOT2(rsiH_off)
1369 rdi_off, SLOT2(rdiH_off)
1370 // saved_rbp_off, SLOT2(saved_rbpH_off)
1371 return_off, SLOT2(returnH_off)
1372 sup_k_off, SLOT2(sup_kH_off)
1373 klass_off, SLOT2(superH_off)
1374 framesize,
1375 result_off = klass_off // deepest argument is also the return value
|