< prev index next >

src/hotspot/cpu/x86/c1_Runtime1_x86.cpp

Print this page

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
< prev index next >