< prev index next >

src/hotspot/cpu/x86/c1_Runtime1_x86.cpp

Print this page

1042       break;
1043 
1044     case C1StubId::new_instance_id:
1045     case C1StubId::fast_new_instance_id:
1046     case C1StubId::fast_new_instance_init_check_id:
1047       {
1048         Register klass = rdx; // Incoming
1049         Register obj   = rax; // Result
1050 
1051         if (id == C1StubId::new_instance_id) {
1052           __ set_info("new_instance", dont_gc_arguments);
1053         } else if (id == C1StubId::fast_new_instance_id) {
1054           __ set_info("fast new_instance", dont_gc_arguments);
1055         } else {
1056           assert(id == C1StubId::fast_new_instance_init_check_id, "bad C1StubId");
1057           __ set_info("fast new_instance init check", dont_gc_arguments);
1058         }
1059 
1060         __ enter();
1061         OopMap* map = save_live_registers(sasm, 2);
1062         int call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_instance), klass);

1063         oop_maps = new OopMapSet();
1064         oop_maps->add_gc_map(call_offset, map);
1065         restore_live_registers_except_rax(sasm);
1066         __ verify_oop(obj);
1067         __ leave();
1068         __ ret(0);
1069 
1070         // rax,: new instance
1071       }
1072 
1073       break;
1074 
1075     case C1StubId::counter_overflow_id:
1076       {
1077         Register bci = rax, method = rbx;
1078         __ enter();
1079         OopMap* map = save_live_registers(sasm, 3);
1080         // Retrieve bci
1081         __ movl(bci, Address(rbp, 2*BytesPerWord));
1082         // And a pointer to the Method*
1083         __ movptr(method, Address(rbp, 3*BytesPerWord));
1084         int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci, method);
1085         oop_maps = new OopMapSet();
1086         oop_maps->add_gc_map(call_offset, map);
1087         restore_live_registers(sasm);
1088         __ leave();
1089         __ ret(0);
1090       }
1091       break;
1092 
1093     case C1StubId::new_type_array_id:
1094     case C1StubId::new_object_array_id:

1095       {
1096         Register length   = rbx; // Incoming
1097         Register klass    = rdx; // Incoming
1098         Register obj      = rax; // Result
1099 
1100         if (id == C1StubId::new_type_array_id) {
1101           __ set_info("new_type_array", dont_gc_arguments);
1102         } else {
1103           __ set_info("new_object_array", dont_gc_arguments);


1104         }
1105 
1106 #ifdef ASSERT
1107         // assert object type is really an array of the proper kind
1108         {
1109           Label ok;
1110           Register t0 = obj;
1111           __ movl(t0, Address(klass, Klass::layout_helper_offset()));
1112           __ sarl(t0, Klass::_lh_array_tag_shift);
1113           int tag = ((id == C1StubId::new_type_array_id)
1114                      ? Klass::_lh_array_tag_type_value
1115                      : Klass::_lh_array_tag_obj_value);
1116           __ cmpl(t0, tag);
1117           __ jcc(Assembler::equal, ok);
1118           __ stop("assert(is an array klass)");
















1119           __ should_not_reach_here();
1120           __ bind(ok);
1121         }
1122 #endif // ASSERT
1123 
1124         __ enter();
1125         OopMap* map = save_live_registers(sasm, 3);
1126         int call_offset;
1127         if (id == C1StubId::new_type_array_id) {
1128           call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_type_array), klass, length);
1129         } else {
1130           call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_object_array), klass, length);



1131         }
1132 
1133         oop_maps = new OopMapSet();
1134         oop_maps->add_gc_map(call_offset, map);
1135         restore_live_registers_except_rax(sasm);
1136 
1137         __ verify_oop(obj);
1138         __ leave();
1139         __ ret(0);
1140 
1141         // rax,: new array
1142       }
1143       break;
1144 
1145     case C1StubId::new_multi_array_id:
1146       { StubFrame f(sasm, "new_multi_array", dont_gc_arguments);
1147         // rax,: klass
1148         // rbx,: rank
1149         // rcx: address of 1st dimension
1150         OopMap* map = save_live_registers(sasm, 4);
1151         int call_offset = __ call_RT(rax, noreg, CAST_FROM_FN_PTR(address, new_multi_array), rax, rbx, rcx);
1152 
1153         oop_maps = new OopMapSet();
1154         oop_maps->add_gc_map(call_offset, map);
1155         restore_live_registers_except_rax(sasm);
1156 
1157         // rax,: new multi array
1158         __ verify_oop(rax);
1159       }
1160       break;
1161 













































































1162     case C1StubId::register_finalizer_id:
1163       {
1164         __ set_info("register_finalizer", dont_gc_arguments);
1165 
1166         // This is called via call_runtime so the arguments
1167         // will be place in C abi locations
1168 
1169 #ifdef _LP64
1170         __ verify_oop(c_rarg0);
1171         __ mov(rax, c_rarg0);
1172 #else
1173         // The object is passed on the stack and we haven't pushed a
1174         // frame yet so it's one work away from top of stack.
1175         __ movptr(rax, Address(rsp, 1 * BytesPerWord));
1176         __ verify_oop(rax);
1177 #endif // _LP64
1178 
1179         // load the klass and check the has finalizer flag
1180         Label register_finalizer;
1181         Register t = rsi;

1242         //       activation and we are calling a leaf VM function only.
1243         generate_unwind_exception(sasm);
1244       }
1245       break;
1246 
1247     case C1StubId::throw_array_store_exception_id:
1248       { StubFrame f(sasm, "throw_array_store_exception", dont_gc_arguments);
1249         // tos + 0: link
1250         //     + 1: return address
1251         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_array_store_exception), true);
1252       }
1253       break;
1254 
1255     case C1StubId::throw_class_cast_exception_id:
1256       { StubFrame f(sasm, "throw_class_cast_exception", dont_gc_arguments);
1257         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_class_cast_exception), true);
1258       }
1259       break;
1260 
1261     case C1StubId::throw_incompatible_class_change_error_id:
1262       { StubFrame f(sasm, "throw_incompatible_class_cast_exception", dont_gc_arguments);
1263         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false);
1264       }
1265       break;
1266 












1267     case C1StubId::slow_subtype_check_id:
1268       {
1269         // Typical calling sequence:
1270         // __ push(klass_RInfo);  // object klass or other subclass
1271         // __ push(sup_k_RInfo);  // array element klass or other superclass
1272         // __ call(slow_subtype_check);
1273         // Note that the subclass is pushed first, and is therefore deepest.
1274         // Previous versions of this code reversed the names 'sub' and 'super'.
1275         // This was operationally harmless but made the code unreadable.
1276         enum layout {
1277           rax_off, SLOT2(raxH_off)
1278           rcx_off, SLOT2(rcxH_off)
1279           rsi_off, SLOT2(rsiH_off)
1280           rdi_off, SLOT2(rdiH_off)
1281           // saved_rbp_off, SLOT2(saved_rbpH_off)
1282           return_off, SLOT2(returnH_off)
1283           sup_k_off, SLOT2(sup_kH_off)
1284           klass_off, SLOT2(superH_off)
1285           framesize,
1286           result_off = klass_off  // deepest argument is also the return value

1042       break;
1043 
1044     case C1StubId::new_instance_id:
1045     case C1StubId::fast_new_instance_id:
1046     case C1StubId::fast_new_instance_init_check_id:
1047       {
1048         Register klass = rdx; // Incoming
1049         Register obj   = rax; // Result
1050 
1051         if (id == C1StubId::new_instance_id) {
1052           __ set_info("new_instance", dont_gc_arguments);
1053         } else if (id == C1StubId::fast_new_instance_id) {
1054           __ set_info("fast new_instance", dont_gc_arguments);
1055         } else {
1056           assert(id == C1StubId::fast_new_instance_init_check_id, "bad C1StubId");
1057           __ set_info("fast new_instance init check", dont_gc_arguments);
1058         }
1059 
1060         __ enter();
1061         OopMap* map = save_live_registers(sasm, 2);
1062         int call_offset;
1063         call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_instance), klass);
1064         oop_maps = new OopMapSet();
1065         oop_maps->add_gc_map(call_offset, map);
1066         restore_live_registers_except_rax(sasm);
1067         __ verify_oop(obj);
1068         __ leave();
1069         __ ret(0);
1070 
1071         // rax,: new instance
1072       }
1073 
1074       break;
1075 
1076     case C1StubId::counter_overflow_id:
1077       {
1078         Register bci = rax, method = rbx;
1079         __ enter();
1080         OopMap* map = save_live_registers(sasm, 3);
1081         // Retrieve bci
1082         __ movl(bci, Address(rbp, 2*BytesPerWord));
1083         // And a pointer to the Method*
1084         __ movptr(method, Address(rbp, 3*BytesPerWord));
1085         int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci, method);
1086         oop_maps = new OopMapSet();
1087         oop_maps->add_gc_map(call_offset, map);
1088         restore_live_registers(sasm);
1089         __ leave();
1090         __ ret(0);
1091       }
1092       break;
1093 
1094     case C1StubId::new_type_array_id:
1095     case C1StubId::new_object_array_id:
1096     case C1StubId::new_null_free_array_id:
1097       {
1098         Register length   = rbx; // Incoming
1099         Register klass    = rdx; // Incoming
1100         Register obj      = rax; // Result
1101 
1102         if (id == C1StubId::new_type_array_id) {
1103           __ set_info("new_type_array", dont_gc_arguments);
1104         } else if (id == C1StubId::new_object_array_id) {
1105           __ set_info("new_object_array", dont_gc_arguments);
1106         } else {
1107           __ set_info("new_null_free_array", dont_gc_arguments);
1108         }
1109 
1110 #ifdef ASSERT
1111         // assert object type is really an array of the proper kind
1112         {
1113           Label ok;
1114           Register t0 = obj;
1115           __ movl(t0, Address(klass, Klass::layout_helper_offset()));
1116           __ sarl(t0, Klass::_lh_array_tag_shift);
1117           switch (id) {
1118           case C1StubId::new_type_array_id:
1119             __ cmpl(t0, Klass::_lh_array_tag_type_value);
1120             __ jcc(Assembler::equal, ok);
1121             __ stop("assert(is a type array klass)");
1122             break;
1123           case C1StubId::new_object_array_id:
1124             __ cmpl(t0, Klass::_lh_array_tag_obj_value); // new "[Ljava/lang/Object;"
1125             __ jcc(Assembler::equal, ok);
1126             __ cmpl(t0, Klass::_lh_array_tag_vt_value);  // new "[LVT;"
1127             __ jcc(Assembler::equal, ok);
1128             __ stop("assert(is an object or inline type array klass)");
1129             break;
1130           case C1StubId::new_null_free_array_id:
1131             __ cmpl(t0, Klass::_lh_array_tag_vt_value);  // the array can be a flat array.
1132             __ jcc(Assembler::equal, ok);
1133             __ cmpl(t0, Klass::_lh_array_tag_obj_value); // the array cannot be a flat array (due to InlineArrayElementMaxFlatSize, etc)
1134             __ jcc(Assembler::equal, ok);
1135             __ stop("assert(is an object or inline type array klass)");
1136             break;
1137           default:  ShouldNotReachHere();
1138           }
1139           __ should_not_reach_here();
1140           __ bind(ok);
1141         }
1142 #endif // ASSERT
1143 
1144         __ enter();
1145         OopMap* map = save_live_registers(sasm, 3);
1146         int call_offset;
1147         if (id == C1StubId::new_type_array_id) {
1148           call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_type_array), klass, length);
1149         } else if (id == C1StubId::new_object_array_id) {
1150           call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_object_array), klass, length);
1151         } else {
1152           assert(id == C1StubId::new_null_free_array_id, "must be");
1153           call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_null_free_array), klass, length);
1154         }
1155 
1156         oop_maps = new OopMapSet();
1157         oop_maps->add_gc_map(call_offset, map);
1158         restore_live_registers_except_rax(sasm);
1159 
1160         __ verify_oop(obj);
1161         __ leave();
1162         __ ret(0);
1163 
1164         // rax,: new array
1165       }
1166       break;
1167 
1168     case C1StubId::new_multi_array_id:
1169       { StubFrame f(sasm, "new_multi_array", dont_gc_arguments);
1170         // rax,: klass
1171         // rbx,: rank
1172         // rcx: address of 1st dimension
1173         OopMap* map = save_live_registers(sasm, 4);
1174         int call_offset = __ call_RT(rax, noreg, CAST_FROM_FN_PTR(address, new_multi_array), rax, rbx, rcx);
1175 
1176         oop_maps = new OopMapSet();
1177         oop_maps->add_gc_map(call_offset, map);
1178         restore_live_registers_except_rax(sasm);
1179 
1180         // rax,: new multi array
1181         __ verify_oop(rax);
1182       }
1183       break;
1184 
1185     case C1StubId::load_flat_array_id:
1186       {
1187         StubFrame f(sasm, "load_flat_array", dont_gc_arguments);
1188         OopMap* map = save_live_registers(sasm, 3);
1189 
1190         // Called with store_parameter and not C abi
1191 
1192         f.load_argument(1, rax); // rax,: array
1193         f.load_argument(0, rbx); // rbx,: index
1194         int call_offset = __ call_RT(rax, noreg, CAST_FROM_FN_PTR(address, load_flat_array), rax, rbx);
1195 
1196         oop_maps = new OopMapSet();
1197         oop_maps->add_gc_map(call_offset, map);
1198         restore_live_registers_except_rax(sasm);
1199 
1200         // rax,: loaded element at array[index]
1201         __ verify_oop(rax);
1202       }
1203       break;
1204 
1205     case C1StubId::store_flat_array_id:
1206       {
1207         StubFrame f(sasm, "store_flat_array", dont_gc_arguments);
1208         OopMap* map = save_live_registers(sasm, 4);
1209 
1210         // Called with store_parameter and not C abi
1211 
1212         f.load_argument(2, rax); // rax,: array
1213         f.load_argument(1, rbx); // rbx,: index
1214         f.load_argument(0, rcx); // rcx,: value
1215         int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, store_flat_array), rax, rbx, rcx);
1216 
1217         oop_maps = new OopMapSet();
1218         oop_maps->add_gc_map(call_offset, map);
1219         restore_live_registers_except_rax(sasm);
1220       }
1221       break;
1222 
1223     case C1StubId::substitutability_check_id:
1224       {
1225         StubFrame f(sasm, "substitutability_check", dont_gc_arguments);
1226         OopMap* map = save_live_registers(sasm, 3);
1227 
1228         // Called with store_parameter and not C abi
1229 
1230         f.load_argument(1, rax); // rax,: left
1231         f.load_argument(0, rbx); // rbx,: right
1232         int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, substitutability_check), rax, rbx);
1233 
1234         oop_maps = new OopMapSet();
1235         oop_maps->add_gc_map(call_offset, map);
1236         restore_live_registers_except_rax(sasm);
1237 
1238         // rax,: are the two operands substitutable
1239       }
1240       break;
1241 
1242 
1243     case C1StubId::buffer_inline_args_id:
1244     case C1StubId::buffer_inline_args_no_receiver_id:
1245       {
1246         const char* name = (id == C1StubId::buffer_inline_args_id) ?
1247           "buffer_inline_args" : "buffer_inline_args_no_receiver";
1248         StubFrame f(sasm, name, dont_gc_arguments);
1249         OopMap* map = save_live_registers(sasm, 2);
1250         Register method = rbx;
1251         address entry = (id == C1StubId::buffer_inline_args_id) ?
1252           CAST_FROM_FN_PTR(address, buffer_inline_args) :
1253           CAST_FROM_FN_PTR(address, buffer_inline_args_no_receiver);
1254         int call_offset = __ call_RT(rax, noreg, entry, method);
1255         oop_maps = new OopMapSet();
1256         oop_maps->add_gc_map(call_offset, map);
1257         restore_live_registers_except_rax(sasm);
1258         __ verify_oop(rax);  // rax: an array of buffered value objects
1259       }
1260       break;
1261 
1262     case C1StubId::register_finalizer_id:
1263       {
1264         __ set_info("register_finalizer", dont_gc_arguments);
1265 
1266         // This is called via call_runtime so the arguments
1267         // will be place in C abi locations
1268 
1269 #ifdef _LP64
1270         __ verify_oop(c_rarg0);
1271         __ mov(rax, c_rarg0);
1272 #else
1273         // The object is passed on the stack and we haven't pushed a
1274         // frame yet so it's one work away from top of stack.
1275         __ movptr(rax, Address(rsp, 1 * BytesPerWord));
1276         __ verify_oop(rax);
1277 #endif // _LP64
1278 
1279         // load the klass and check the has finalizer flag
1280         Label register_finalizer;
1281         Register t = rsi;

1342         //       activation and we are calling a leaf VM function only.
1343         generate_unwind_exception(sasm);
1344       }
1345       break;
1346 
1347     case C1StubId::throw_array_store_exception_id:
1348       { StubFrame f(sasm, "throw_array_store_exception", dont_gc_arguments);
1349         // tos + 0: link
1350         //     + 1: return address
1351         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_array_store_exception), true);
1352       }
1353       break;
1354 
1355     case C1StubId::throw_class_cast_exception_id:
1356       { StubFrame f(sasm, "throw_class_cast_exception", dont_gc_arguments);
1357         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_class_cast_exception), true);
1358       }
1359       break;
1360 
1361     case C1StubId::throw_incompatible_class_change_error_id:
1362       { StubFrame f(sasm, "throw_incompatible_class_change_error", dont_gc_arguments);
1363         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false);
1364       }
1365       break;
1366 
1367     case C1StubId::throw_illegal_monitor_state_exception_id:
1368       { StubFrame f(sasm, "throw_illegal_monitor_state_exception", dont_gc_arguments);
1369         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_illegal_monitor_state_exception), false);
1370       }
1371       break;
1372 
1373     case C1StubId::throw_identity_exception_id:
1374       { StubFrame f(sasm, "throw_identity_exception", dont_gc_arguments);
1375         oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_identity_exception), true);
1376       }
1377       break;
1378 
1379     case C1StubId::slow_subtype_check_id:
1380       {
1381         // Typical calling sequence:
1382         // __ push(klass_RInfo);  // object klass or other subclass
1383         // __ push(sup_k_RInfo);  // array element klass or other superclass
1384         // __ call(slow_subtype_check);
1385         // Note that the subclass is pushed first, and is therefore deepest.
1386         // Previous versions of this code reversed the names 'sub' and 'super'.
1387         // This was operationally harmless but made the code unreadable.
1388         enum layout {
1389           rax_off, SLOT2(raxH_off)
1390           rcx_off, SLOT2(rcxH_off)
1391           rsi_off, SLOT2(rsiH_off)
1392           rdi_off, SLOT2(rdiH_off)
1393           // saved_rbp_off, SLOT2(saved_rbpH_off)
1394           return_off, SLOT2(returnH_off)
1395           sup_k_off, SLOT2(sup_kH_off)
1396           klass_off, SLOT2(superH_off)
1397           framesize,
1398           result_off = klass_off  // deepest argument is also the return value
< prev index next >