Mercurial > hg > truffle
comparison src/cpu/x86/vm/sharedRuntime_x86_64.cpp @ 4970:33df1aeaebbf
Merge with http://hg.openjdk.java.net/hsx/hsx24/hotspot/
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Mon, 27 Feb 2012 13:10:13 +0100 |
parents | 74c0b866fe8d 0382d2b469b2 |
children | 18a5539bf19b |
comparison
equal
deleted
inserted
replaced
4703:2cfb7fb2dce7 | 4970:33df1aeaebbf |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
937 __ movq(dst.first()->as_Register(), src.first()->as_Register()); | 937 __ movq(dst.first()->as_Register(), src.first()->as_Register()); |
938 } | 938 } |
939 } | 939 } |
940 } | 940 } |
941 | 941 |
942 static void move_ptr(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { | |
943 if (src.first()->is_stack()) { | |
944 if (dst.first()->is_stack()) { | |
945 // stack to stack | |
946 __ movq(rax, Address(rbp, reg2offset_in(src.first()))); | |
947 __ movq(Address(rsp, reg2offset_out(dst.first())), rax); | |
948 } else { | |
949 // stack to reg | |
950 __ movq(dst.first()->as_Register(), Address(rbp, reg2offset_in(src.first()))); | |
951 } | |
952 } else if (dst.first()->is_stack()) { | |
953 // reg to stack | |
954 __ movq(Address(rsp, reg2offset_out(dst.first())), src.first()->as_Register()); | |
955 } else { | |
956 if (dst.first() != src.first()) { | |
957 __ movq(dst.first()->as_Register(), src.first()->as_Register()); | |
958 } | |
959 } | |
960 } | |
942 | 961 |
943 // An oop arg. Must pass a handle not the oop itself | 962 // An oop arg. Must pass a handle not the oop itself |
944 static void object_move(MacroAssembler* masm, | 963 static void object_move(MacroAssembler* masm, |
945 OopMap* map, | 964 OopMap* map, |
946 int oop_handle_offset, | 965 int oop_handle_offset, |
1151 __ addptr(rsp, 2*wordSize); | 1170 __ addptr(rsp, 2*wordSize); |
1152 } | 1171 } |
1153 } | 1172 } |
1154 } | 1173 } |
1155 | 1174 |
1175 | |
1176 static void save_or_restore_arguments(MacroAssembler* masm, | |
1177 const int stack_slots, | |
1178 const int total_in_args, | |
1179 const int arg_save_area, | |
1180 OopMap* map, | |
1181 VMRegPair* in_regs, | |
1182 BasicType* in_sig_bt) { | |
1183 // if map is non-NULL then the code should store the values, | |
1184 // otherwise it should load them. | |
1185 int handle_index = 0; | |
1186 // Save down double word first | |
1187 for ( int i = 0; i < total_in_args; i++) { | |
1188 if (in_regs[i].first()->is_XMMRegister() && in_sig_bt[i] == T_DOUBLE) { | |
1189 int slot = handle_index * VMRegImpl::slots_per_word + arg_save_area; | |
1190 int offset = slot * VMRegImpl::stack_slot_size; | |
1191 handle_index += 2; | |
1192 assert(handle_index <= stack_slots, "overflow"); | |
1193 if (map != NULL) { | |
1194 __ movdbl(Address(rsp, offset), in_regs[i].first()->as_XMMRegister()); | |
1195 } else { | |
1196 __ movdbl(in_regs[i].first()->as_XMMRegister(), Address(rsp, offset)); | |
1197 } | |
1198 } | |
1199 if (in_regs[i].first()->is_Register() && | |
1200 (in_sig_bt[i] == T_LONG || in_sig_bt[i] == T_ARRAY)) { | |
1201 int slot = handle_index * VMRegImpl::slots_per_word + arg_save_area; | |
1202 int offset = slot * VMRegImpl::stack_slot_size; | |
1203 handle_index += 2; | |
1204 assert(handle_index <= stack_slots, "overflow"); | |
1205 if (map != NULL) { | |
1206 __ movq(Address(rsp, offset), in_regs[i].first()->as_Register()); | |
1207 if (in_sig_bt[i] == T_ARRAY) { | |
1208 map->set_oop(VMRegImpl::stack2reg(slot));; | |
1209 } | |
1210 } else { | |
1211 __ movq(in_regs[i].first()->as_Register(), Address(rsp, offset)); | |
1212 } | |
1213 } | |
1214 } | |
1215 // Save or restore single word registers | |
1216 for ( int i = 0; i < total_in_args; i++) { | |
1217 if (in_regs[i].first()->is_Register()) { | |
1218 int slot = handle_index++ * VMRegImpl::slots_per_word + arg_save_area; | |
1219 int offset = slot * VMRegImpl::stack_slot_size; | |
1220 assert(handle_index <= stack_slots, "overflow"); | |
1221 | |
1222 // Value is in an input register pass we must flush it to the stack | |
1223 const Register reg = in_regs[i].first()->as_Register(); | |
1224 switch (in_sig_bt[i]) { | |
1225 case T_BOOLEAN: | |
1226 case T_CHAR: | |
1227 case T_BYTE: | |
1228 case T_SHORT: | |
1229 case T_INT: | |
1230 if (map != NULL) { | |
1231 __ movl(Address(rsp, offset), reg); | |
1232 } else { | |
1233 __ movl(reg, Address(rsp, offset)); | |
1234 } | |
1235 break; | |
1236 case T_ARRAY: | |
1237 case T_LONG: | |
1238 // handled above | |
1239 break; | |
1240 case T_OBJECT: | |
1241 default: ShouldNotReachHere(); | |
1242 } | |
1243 } else if (in_regs[i].first()->is_XMMRegister()) { | |
1244 if (in_sig_bt[i] == T_FLOAT) { | |
1245 int slot = handle_index++ * VMRegImpl::slots_per_word + arg_save_area; | |
1246 int offset = slot * VMRegImpl::stack_slot_size; | |
1247 assert(handle_index <= stack_slots, "overflow"); | |
1248 if (map != NULL) { | |
1249 __ movflt(Address(rsp, offset), in_regs[i].first()->as_XMMRegister()); | |
1250 } else { | |
1251 __ movflt(in_regs[i].first()->as_XMMRegister(), Address(rsp, offset)); | |
1252 } | |
1253 } | |
1254 } else if (in_regs[i].first()->is_stack()) { | |
1255 if (in_sig_bt[i] == T_ARRAY && map != NULL) { | |
1256 int offset_in_older_frame = in_regs[i].first()->reg2stack() + SharedRuntime::out_preserve_stack_slots(); | |
1257 map->set_oop(VMRegImpl::stack2reg(offset_in_older_frame + stack_slots)); | |
1258 } | |
1259 } | |
1260 } | |
1261 } | |
1262 | |
1263 | |
1264 // Check GC_locker::needs_gc and enter the runtime if it's true. This | |
1265 // keeps a new JNI critical region from starting until a GC has been | |
1266 // forced. Save down any oops in registers and describe them in an | |
1267 // OopMap. | |
1268 static void check_needs_gc_for_critical_native(MacroAssembler* masm, | |
1269 int stack_slots, | |
1270 int total_c_args, | |
1271 int total_in_args, | |
1272 int arg_save_area, | |
1273 OopMapSet* oop_maps, | |
1274 VMRegPair* in_regs, | |
1275 BasicType* in_sig_bt) { | |
1276 __ block_comment("check GC_locker::needs_gc"); | |
1277 Label cont; | |
1278 __ cmp8(ExternalAddress((address)GC_locker::needs_gc_address()), false); | |
1279 __ jcc(Assembler::equal, cont); | |
1280 | |
1281 // Save down any incoming oops and call into the runtime to halt for a GC | |
1282 | |
1283 OopMap* map = new OopMap(stack_slots * 2, 0 /* arg_slots*/); | |
1284 save_or_restore_arguments(masm, stack_slots, total_in_args, | |
1285 arg_save_area, map, in_regs, in_sig_bt); | |
1286 | |
1287 address the_pc = __ pc(); | |
1288 oop_maps->add_gc_map( __ offset(), map); | |
1289 __ set_last_Java_frame(rsp, noreg, the_pc); | |
1290 | |
1291 __ block_comment("block_for_jni_critical"); | |
1292 __ movptr(c_rarg0, r15_thread); | |
1293 __ mov(r12, rsp); // remember sp | |
1294 __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows | |
1295 __ andptr(rsp, -16); // align stack as required by ABI | |
1296 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::block_for_jni_critical))); | |
1297 __ mov(rsp, r12); // restore sp | |
1298 __ reinit_heapbase(); | |
1299 | |
1300 __ reset_last_Java_frame(false, true); | |
1301 | |
1302 save_or_restore_arguments(masm, stack_slots, total_in_args, | |
1303 arg_save_area, NULL, in_regs, in_sig_bt); | |
1304 | |
1305 __ bind(cont); | |
1306 #ifdef ASSERT | |
1307 if (StressCriticalJNINatives) { | |
1308 // Stress register saving | |
1309 OopMap* map = new OopMap(stack_slots * 2, 0 /* arg_slots*/); | |
1310 save_or_restore_arguments(masm, stack_slots, total_in_args, | |
1311 arg_save_area, map, in_regs, in_sig_bt); | |
1312 // Destroy argument registers | |
1313 for (int i = 0; i < total_in_args - 1; i++) { | |
1314 if (in_regs[i].first()->is_Register()) { | |
1315 const Register reg = in_regs[i].first()->as_Register(); | |
1316 __ xorptr(reg, reg); | |
1317 } else if (in_regs[i].first()->is_XMMRegister()) { | |
1318 __ xorpd(in_regs[i].first()->as_XMMRegister(), in_regs[i].first()->as_XMMRegister()); | |
1319 } else if (in_regs[i].first()->is_FloatRegister()) { | |
1320 ShouldNotReachHere(); | |
1321 } else if (in_regs[i].first()->is_stack()) { | |
1322 // Nothing to do | |
1323 } else { | |
1324 ShouldNotReachHere(); | |
1325 } | |
1326 if (in_sig_bt[i] == T_LONG || in_sig_bt[i] == T_DOUBLE) { | |
1327 i++; | |
1328 } | |
1329 } | |
1330 | |
1331 save_or_restore_arguments(masm, stack_slots, total_in_args, | |
1332 arg_save_area, NULL, in_regs, in_sig_bt); | |
1333 } | |
1334 #endif | |
1335 } | |
1336 | |
1337 // Unpack an array argument into a pointer to the body and the length | |
1338 // if the array is non-null, otherwise pass 0 for both. | |
1339 static void unpack_array_argument(MacroAssembler* masm, VMRegPair reg, BasicType in_elem_type, VMRegPair body_arg, VMRegPair length_arg) { | |
1340 Register tmp_reg = rax; | |
1341 assert(!body_arg.first()->is_Register() || body_arg.first()->as_Register() != tmp_reg, | |
1342 "possible collision"); | |
1343 assert(!length_arg.first()->is_Register() || length_arg.first()->as_Register() != tmp_reg, | |
1344 "possible collision"); | |
1345 | |
1346 // Pass the length, ptr pair | |
1347 Label is_null, done; | |
1348 VMRegPair tmp; | |
1349 tmp.set_ptr(tmp_reg->as_VMReg()); | |
1350 if (reg.first()->is_stack()) { | |
1351 // Load the arg up from the stack | |
1352 move_ptr(masm, reg, tmp); | |
1353 reg = tmp; | |
1354 } | |
1355 __ testptr(reg.first()->as_Register(), reg.first()->as_Register()); | |
1356 __ jccb(Assembler::equal, is_null); | |
1357 __ lea(tmp_reg, Address(reg.first()->as_Register(), arrayOopDesc::base_offset_in_bytes(in_elem_type))); | |
1358 move_ptr(masm, tmp, body_arg); | |
1359 // load the length relative to the body. | |
1360 __ movl(tmp_reg, Address(tmp_reg, arrayOopDesc::length_offset_in_bytes() - | |
1361 arrayOopDesc::base_offset_in_bytes(in_elem_type))); | |
1362 move32_64(masm, tmp, length_arg); | |
1363 __ jmpb(done); | |
1364 __ bind(is_null); | |
1365 // Pass zeros | |
1366 __ xorptr(tmp_reg, tmp_reg); | |
1367 move_ptr(masm, tmp, body_arg); | |
1368 move32_64(masm, tmp, length_arg); | |
1369 __ bind(done); | |
1370 } | |
1371 | |
1156 // --------------------------------------------------------------------------- | 1372 // --------------------------------------------------------------------------- |
1157 // Generate a native wrapper for a given method. The method takes arguments | 1373 // Generate a native wrapper for a given method. The method takes arguments |
1158 // in the Java compiled code convention, marshals them to the native | 1374 // in the Java compiled code convention, marshals them to the native |
1159 // convention (handlizes oops, etc), transitions to native, makes the call, | 1375 // convention (handlizes oops, etc), transitions to native, makes the call, |
1160 // returns to java state (possibly blocking), unhandlizes any result and | 1376 // returns to java state (possibly blocking), unhandlizes any result and |
1165 int total_in_args, | 1381 int total_in_args, |
1166 int comp_args_on_stack, | 1382 int comp_args_on_stack, |
1167 BasicType *in_sig_bt, | 1383 BasicType *in_sig_bt, |
1168 VMRegPair *in_regs, | 1384 VMRegPair *in_regs, |
1169 BasicType ret_type) { | 1385 BasicType ret_type) { |
1170 // Native nmethod wrappers never take possesion of the oop arguments. | 1386 bool is_critical_native = true; |
1171 // So the caller will gc the arguments. The only thing we need an | 1387 address native_func = method->critical_native_function(); |
1172 // oopMap for is if the call is static | 1388 if (native_func == NULL) { |
1173 // | 1389 native_func = method->native_function(); |
1390 is_critical_native = false; | |
1391 } | |
1392 assert(native_func != NULL, "must have function"); | |
1393 | |
1174 // An OopMap for lock (and class if static) | 1394 // An OopMap for lock (and class if static) |
1175 OopMapSet *oop_maps = new OopMapSet(); | 1395 OopMapSet *oop_maps = new OopMapSet(); |
1176 intptr_t start = (intptr_t)__ pc(); | 1396 intptr_t start = (intptr_t)__ pc(); |
1177 | 1397 |
1178 // We have received a description of where all the java arg are located | 1398 // We have received a description of where all the java arg are located |
1179 // on entry to the wrapper. We need to convert these args to where | 1399 // on entry to the wrapper. We need to convert these args to where |
1180 // the jni function will expect them. To figure out where they go | 1400 // the jni function will expect them. To figure out where they go |
1181 // we convert the java signature to a C signature by inserting | 1401 // we convert the java signature to a C signature by inserting |
1182 // the hidden arguments as arg[0] and possibly arg[1] (static method) | 1402 // the hidden arguments as arg[0] and possibly arg[1] (static method) |
1183 | 1403 |
1184 int total_c_args = total_in_args + 1; | 1404 int total_c_args = total_in_args; |
1185 if (method->is_static()) { | 1405 if (!is_critical_native) { |
1186 total_c_args++; | 1406 total_c_args += 1; |
1407 if (method->is_static()) { | |
1408 total_c_args++; | |
1409 } | |
1410 } else { | |
1411 for (int i = 0; i < total_in_args; i++) { | |
1412 if (in_sig_bt[i] == T_ARRAY) { | |
1413 total_c_args++; | |
1414 } | |
1415 } | |
1187 } | 1416 } |
1188 | 1417 |
1189 BasicType* out_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_c_args); | 1418 BasicType* out_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_c_args); |
1190 VMRegPair* out_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_c_args); | 1419 VMRegPair* out_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_c_args); |
1420 BasicType* in_elem_bt = NULL; | |
1191 | 1421 |
1192 int argc = 0; | 1422 int argc = 0; |
1193 out_sig_bt[argc++] = T_ADDRESS; | 1423 if (!is_critical_native) { |
1194 if (method->is_static()) { | 1424 out_sig_bt[argc++] = T_ADDRESS; |
1195 out_sig_bt[argc++] = T_OBJECT; | 1425 if (method->is_static()) { |
1196 } | 1426 out_sig_bt[argc++] = T_OBJECT; |
1197 | 1427 } |
1198 for (int i = 0; i < total_in_args ; i++ ) { | 1428 |
1199 out_sig_bt[argc++] = in_sig_bt[i]; | 1429 for (int i = 0; i < total_in_args ; i++ ) { |
1430 out_sig_bt[argc++] = in_sig_bt[i]; | |
1431 } | |
1432 } else { | |
1433 Thread* THREAD = Thread::current(); | |
1434 in_elem_bt = NEW_RESOURCE_ARRAY(BasicType, total_in_args); | |
1435 SignatureStream ss(method->signature()); | |
1436 for (int i = 0; i < total_in_args ; i++ ) { | |
1437 if (in_sig_bt[i] == T_ARRAY) { | |
1438 // Arrays are passed as int, elem* pair | |
1439 out_sig_bt[argc++] = T_INT; | |
1440 out_sig_bt[argc++] = T_ADDRESS; | |
1441 Symbol* atype = ss.as_symbol(CHECK_NULL); | |
1442 const char* at = atype->as_C_string(); | |
1443 if (strlen(at) == 2) { | |
1444 assert(at[0] == '[', "must be"); | |
1445 switch (at[1]) { | |
1446 case 'B': in_elem_bt[i] = T_BYTE; break; | |
1447 case 'C': in_elem_bt[i] = T_CHAR; break; | |
1448 case 'D': in_elem_bt[i] = T_DOUBLE; break; | |
1449 case 'F': in_elem_bt[i] = T_FLOAT; break; | |
1450 case 'I': in_elem_bt[i] = T_INT; break; | |
1451 case 'J': in_elem_bt[i] = T_LONG; break; | |
1452 case 'S': in_elem_bt[i] = T_SHORT; break; | |
1453 case 'Z': in_elem_bt[i] = T_BOOLEAN; break; | |
1454 default: ShouldNotReachHere(); | |
1455 } | |
1456 } | |
1457 } else { | |
1458 out_sig_bt[argc++] = in_sig_bt[i]; | |
1459 in_elem_bt[i] = T_VOID; | |
1460 } | |
1461 if (in_sig_bt[i] != T_VOID) { | |
1462 assert(in_sig_bt[i] == ss.type(), "must match"); | |
1463 ss.next(); | |
1464 } | |
1465 } | |
1200 } | 1466 } |
1201 | 1467 |
1202 // Now figure out where the args must be stored and how much stack space | 1468 // Now figure out where the args must be stored and how much stack space |
1203 // they require. | 1469 // they require. |
1204 // | |
1205 int out_arg_slots; | 1470 int out_arg_slots; |
1206 out_arg_slots = c_calling_convention(out_sig_bt, out_regs, total_c_args); | 1471 out_arg_slots = c_calling_convention(out_sig_bt, out_regs, total_c_args); |
1207 | 1472 |
1208 // Compute framesize for the wrapper. We need to handlize all oops in | 1473 // Compute framesize for the wrapper. We need to handlize all oops in |
1209 // incoming registers | 1474 // incoming registers |
1212 | 1477 |
1213 // First count the abi requirement plus all of the outgoing args | 1478 // First count the abi requirement plus all of the outgoing args |
1214 int stack_slots = SharedRuntime::out_preserve_stack_slots() + out_arg_slots; | 1479 int stack_slots = SharedRuntime::out_preserve_stack_slots() + out_arg_slots; |
1215 | 1480 |
1216 // Now the space for the inbound oop handle area | 1481 // Now the space for the inbound oop handle area |
1482 int total_save_slots = 6 * VMRegImpl::slots_per_word; // 6 arguments passed in registers | |
1483 if (is_critical_native) { | |
1484 // Critical natives may have to call out so they need a save area | |
1485 // for register arguments. | |
1486 int double_slots = 0; | |
1487 int single_slots = 0; | |
1488 for ( int i = 0; i < total_in_args; i++) { | |
1489 if (in_regs[i].first()->is_Register()) { | |
1490 const Register reg = in_regs[i].first()->as_Register(); | |
1491 switch (in_sig_bt[i]) { | |
1492 case T_ARRAY: | |
1493 case T_BOOLEAN: | |
1494 case T_BYTE: | |
1495 case T_SHORT: | |
1496 case T_CHAR: | |
1497 case T_INT: single_slots++; break; | |
1498 case T_LONG: double_slots++; break; | |
1499 default: ShouldNotReachHere(); | |
1500 } | |
1501 } else if (in_regs[i].first()->is_XMMRegister()) { | |
1502 switch (in_sig_bt[i]) { | |
1503 case T_FLOAT: single_slots++; break; | |
1504 case T_DOUBLE: double_slots++; break; | |
1505 default: ShouldNotReachHere(); | |
1506 } | |
1507 } else if (in_regs[i].first()->is_FloatRegister()) { | |
1508 ShouldNotReachHere(); | |
1509 } | |
1510 } | |
1511 total_save_slots = double_slots * 2 + single_slots; | |
1512 // align the save area | |
1513 if (double_slots != 0) { | |
1514 stack_slots = round_to(stack_slots, 2); | |
1515 } | |
1516 } | |
1217 | 1517 |
1218 int oop_handle_offset = stack_slots; | 1518 int oop_handle_offset = stack_slots; |
1219 stack_slots += 6*VMRegImpl::slots_per_word; | 1519 stack_slots += total_save_slots; |
1220 | 1520 |
1221 // Now any space we need for handlizing a klass if static method | 1521 // Now any space we need for handlizing a klass if static method |
1222 | 1522 |
1223 int oop_temp_slot_offset = 0; | |
1224 int klass_slot_offset = 0; | 1523 int klass_slot_offset = 0; |
1225 int klass_offset = -1; | 1524 int klass_offset = -1; |
1226 int lock_slot_offset = 0; | 1525 int lock_slot_offset = 0; |
1227 bool is_static = false; | 1526 bool is_static = false; |
1228 | 1527 |
1271 // stack properly aligned. | 1570 // stack properly aligned. |
1272 stack_slots = round_to(stack_slots, StackAlignmentInSlots); | 1571 stack_slots = round_to(stack_slots, StackAlignmentInSlots); |
1273 | 1572 |
1274 int stack_size = stack_slots * VMRegImpl::stack_slot_size; | 1573 int stack_size = stack_slots * VMRegImpl::stack_slot_size; |
1275 | 1574 |
1276 | |
1277 // First thing make an ic check to see if we should even be here | 1575 // First thing make an ic check to see if we should even be here |
1278 | 1576 |
1279 // We are free to use all registers as temps without saving them and | 1577 // We are free to use all registers as temps without saving them and |
1280 // restoring them except rbp. rbp is the only callee save register | 1578 // restoring them except rbp. rbp is the only callee save register |
1281 // as far as the interpreter and the compiler(s) are concerned. | 1579 // as far as the interpreter and the compiler(s) are concerned. |
1282 | 1580 |
1283 | 1581 |
1284 const Register ic_reg = rax; | 1582 const Register ic_reg = rax; |
1285 const Register receiver = j_rarg0; | 1583 const Register receiver = j_rarg0; |
1286 | 1584 |
1287 Label ok; | 1585 Label hit; |
1288 Label exception_pending; | 1586 Label exception_pending; |
1289 | 1587 |
1290 assert_different_registers(ic_reg, receiver, rscratch1); | 1588 assert_different_registers(ic_reg, receiver, rscratch1); |
1291 __ verify_oop(receiver); | 1589 __ verify_oop(receiver); |
1292 __ load_klass(rscratch1, receiver); | 1590 __ load_klass(rscratch1, receiver); |
1293 __ cmpq(ic_reg, rscratch1); | 1591 __ cmpq(ic_reg, rscratch1); |
1294 __ jcc(Assembler::equal, ok); | 1592 __ jcc(Assembler::equal, hit); |
1295 | 1593 |
1296 __ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); | 1594 __ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); |
1297 | |
1298 __ bind(ok); | |
1299 | 1595 |
1300 // Verified entry point must be aligned | 1596 // Verified entry point must be aligned |
1301 __ align(8); | 1597 __ align(8); |
1598 | |
1599 __ bind(hit); | |
1302 | 1600 |
1303 int vep_offset = ((intptr_t)__ pc()) - start; | 1601 int vep_offset = ((intptr_t)__ pc()) - start; |
1304 | 1602 |
1305 // The instruction at the verified entry point must be 5 bytes or longer | 1603 // The instruction at the verified entry point must be 5 bytes or longer |
1306 // because it can be patched on the fly by make_non_entrant. The stack bang | 1604 // because it can be patched on the fly by make_non_entrant. The stack bang |
1318 // Generate a new frame for the wrapper. | 1616 // Generate a new frame for the wrapper. |
1319 __ enter(); | 1617 __ enter(); |
1320 // -2 because return address is already present and so is saved rbp | 1618 // -2 because return address is already present and so is saved rbp |
1321 __ subptr(rsp, stack_size - 2*wordSize); | 1619 __ subptr(rsp, stack_size - 2*wordSize); |
1322 | 1620 |
1323 // Frame is now completed as far as size and linkage. | 1621 // Frame is now completed as far as size and linkage. |
1324 | 1622 int frame_complete = ((intptr_t)__ pc()) - start; |
1325 int frame_complete = ((intptr_t)__ pc()) - start; | |
1326 | 1623 |
1327 #ifdef ASSERT | 1624 #ifdef ASSERT |
1328 { | 1625 { |
1329 Label L; | 1626 Label L; |
1330 __ mov(rax, rsp); | 1627 __ mov(rax, rsp); |
1340 // We use r14 as the oop handle for the receiver/klass | 1637 // We use r14 as the oop handle for the receiver/klass |
1341 // It is callee save so it survives the call to native | 1638 // It is callee save so it survives the call to native |
1342 | 1639 |
1343 const Register oop_handle_reg = r14; | 1640 const Register oop_handle_reg = r14; |
1344 | 1641 |
1345 | 1642 if (is_critical_native) { |
1643 check_needs_gc_for_critical_native(masm, stack_slots, total_c_args, total_in_args, | |
1644 oop_handle_offset, oop_maps, in_regs, in_sig_bt); | |
1645 } | |
1346 | 1646 |
1347 // | 1647 // |
1348 // We immediately shuffle the arguments so that any vm call we have to | 1648 // We immediately shuffle the arguments so that any vm call we have to |
1349 // make from here on out (sync slow path, jvmti, etc.) we will have | 1649 // make from here on out (sync slow path, jvmti, etc.) we will have |
1350 // captured the oops from our caller and have a valid oopMap for | 1650 // captured the oops from our caller and have a valid oopMap for |
1389 freg_destroyed[f] = false; | 1689 freg_destroyed[f] = false; |
1390 } | 1690 } |
1391 | 1691 |
1392 #endif /* ASSERT */ | 1692 #endif /* ASSERT */ |
1393 | 1693 |
1394 | 1694 if (is_critical_native) { |
1695 // The mapping of Java and C arguments passed in registers are | |
1696 // rotated by one, which helps when passing arguments to regular | |
1697 // Java method but for critical natives that creates a cycle which | |
1698 // can cause arguments to be killed before they are used. Break | |
1699 // the cycle by moving the first argument into a temporary | |
1700 // register. | |
1701 for (int i = 0; i < total_c_args; i++) { | |
1702 if (in_regs[i].first()->is_Register() && | |
1703 in_regs[i].first()->as_Register() == rdi) { | |
1704 __ mov(rbx, rdi); | |
1705 in_regs[i].set1(rbx->as_VMReg()); | |
1706 } | |
1707 } | |
1708 } | |
1709 | |
1710 // This may iterate in two different directions depending on the | |
1711 // kind of native it is. The reason is that for regular JNI natives | |
1712 // the incoming and outgoing registers are offset upwards and for | |
1713 // critical natives they are offset down. | |
1395 int c_arg = total_c_args - 1; | 1714 int c_arg = total_c_args - 1; |
1396 for ( int i = total_in_args - 1; i >= 0 ; i--, c_arg-- ) { | 1715 int stride = -1; |
1716 int init = total_in_args - 1; | |
1717 if (is_critical_native) { | |
1718 // stride forwards | |
1719 c_arg = 0; | |
1720 stride = 1; | |
1721 init = 0; | |
1722 } | |
1723 for (int i = init, count = 0; count < total_in_args; i += stride, c_arg += stride, count++ ) { | |
1397 #ifdef ASSERT | 1724 #ifdef ASSERT |
1398 if (in_regs[i].first()->is_Register()) { | 1725 if (in_regs[i].first()->is_Register()) { |
1399 assert(!reg_destroyed[in_regs[i].first()->as_Register()->encoding()], "destroyed reg!"); | 1726 assert(!reg_destroyed[in_regs[i].first()->as_Register()->encoding()], "destroyed reg!"); |
1400 } else if (in_regs[i].first()->is_XMMRegister()) { | 1727 } else if (in_regs[i].first()->is_XMMRegister()) { |
1401 assert(!freg_destroyed[in_regs[i].first()->as_XMMRegister()->encoding()], "destroyed reg!"); | 1728 assert(!freg_destroyed[in_regs[i].first()->as_XMMRegister()->encoding()], "destroyed reg!"); |
1406 freg_destroyed[out_regs[c_arg].first()->as_XMMRegister()->encoding()] = true; | 1733 freg_destroyed[out_regs[c_arg].first()->as_XMMRegister()->encoding()] = true; |
1407 } | 1734 } |
1408 #endif /* ASSERT */ | 1735 #endif /* ASSERT */ |
1409 switch (in_sig_bt[i]) { | 1736 switch (in_sig_bt[i]) { |
1410 case T_ARRAY: | 1737 case T_ARRAY: |
1738 if (is_critical_native) { | |
1739 unpack_array_argument(masm, in_regs[i], in_elem_bt[i], out_regs[c_arg + 1], out_regs[c_arg]); | |
1740 c_arg++; | |
1741 #ifdef ASSERT | |
1742 if (out_regs[c_arg].first()->is_Register()) { | |
1743 reg_destroyed[out_regs[c_arg].first()->as_Register()->encoding()] = true; | |
1744 } else if (out_regs[c_arg].first()->is_XMMRegister()) { | |
1745 freg_destroyed[out_regs[c_arg].first()->as_XMMRegister()->encoding()] = true; | |
1746 } | |
1747 #endif | |
1748 break; | |
1749 } | |
1411 case T_OBJECT: | 1750 case T_OBJECT: |
1751 assert(!is_critical_native, "no oop arguments"); | |
1412 object_move(masm, map, oop_handle_offset, stack_slots, in_regs[i], out_regs[c_arg], | 1752 object_move(masm, map, oop_handle_offset, stack_slots, in_regs[i], out_regs[c_arg], |
1413 ((i == 0) && (!is_static)), | 1753 ((i == 0) && (!is_static)), |
1414 &receiver_offset); | 1754 &receiver_offset); |
1415 break; | 1755 break; |
1416 case T_VOID: | 1756 case T_VOID: |
1442 // need to spill before we call out | 1782 // need to spill before we call out |
1443 c_arg++; | 1783 c_arg++; |
1444 | 1784 |
1445 // Pre-load a static method's oop into r14. Used both by locking code and | 1785 // Pre-load a static method's oop into r14. Used both by locking code and |
1446 // the normal JNI call code. | 1786 // the normal JNI call code. |
1447 if (method->is_static()) { | 1787 if (method->is_static() && !is_critical_native) { |
1448 | 1788 |
1449 // load oop into a register | 1789 // load oop into a register |
1450 __ movoop(oop_handle_reg, JNIHandles::make_local(Klass::cast(method->method_holder())->java_mirror())); | 1790 __ movoop(oop_handle_reg, JNIHandles::make_local(Klass::cast(method->method_holder())->java_mirror())); |
1451 | 1791 |
1452 // Now handlize the static class mirror it's known not-null. | 1792 // Now handlize the static class mirror it's known not-null. |
1508 | 1848 |
1509 Label slow_path_lock; | 1849 Label slow_path_lock; |
1510 Label lock_done; | 1850 Label lock_done; |
1511 | 1851 |
1512 if (method->is_synchronized()) { | 1852 if (method->is_synchronized()) { |
1853 assert(!is_critical_native, "unhandled"); | |
1513 | 1854 |
1514 | 1855 |
1515 const int mark_word_offset = BasicLock::displaced_header_offset_in_bytes(); | 1856 const int mark_word_offset = BasicLock::displaced_header_offset_in_bytes(); |
1516 | 1857 |
1517 // Get the handle (the 2nd argument) | 1858 // Get the handle (the 2nd argument) |
1571 | 1912 |
1572 // Finally just about ready to make the JNI call | 1913 // Finally just about ready to make the JNI call |
1573 | 1914 |
1574 | 1915 |
1575 // get JNIEnv* which is first argument to native | 1916 // get JNIEnv* which is first argument to native |
1576 | 1917 if (!is_critical_native) { |
1577 __ lea(c_rarg0, Address(r15_thread, in_bytes(JavaThread::jni_environment_offset()))); | 1918 __ lea(c_rarg0, Address(r15_thread, in_bytes(JavaThread::jni_environment_offset()))); |
1919 } | |
1578 | 1920 |
1579 // Now set thread in native | 1921 // Now set thread in native |
1580 __ movl(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_native); | 1922 __ movl(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_native); |
1581 | 1923 |
1582 __ call(RuntimeAddress(method->native_function())); | 1924 __ call(RuntimeAddress(native_func)); |
1583 | 1925 |
1584 // Either restore the MXCSR register after returning from the JNI Call | 1926 // Either restore the MXCSR register after returning from the JNI Call |
1585 // or verify that it wasn't changed. | 1927 // or verify that it wasn't changed. |
1586 if (RestoreMXCSROnJNICalls) { | 1928 if (RestoreMXCSROnJNICalls) { |
1587 __ ldmxcsr(ExternalAddress(StubRoutines::x86::mxcsr_std())); | 1929 __ ldmxcsr(ExternalAddress(StubRoutines::x86::mxcsr_std())); |
1633 // due to cache line collision. | 1975 // due to cache line collision. |
1634 __ serialize_memory(r15_thread, rcx); | 1976 __ serialize_memory(r15_thread, rcx); |
1635 } | 1977 } |
1636 } | 1978 } |
1637 | 1979 |
1980 Label after_transition; | |
1638 | 1981 |
1639 // check for safepoint operation in progress and/or pending suspend requests | 1982 // check for safepoint operation in progress and/or pending suspend requests |
1640 { | 1983 { |
1641 Label Continue; | 1984 Label Continue; |
1642 | 1985 |
1658 save_native_result(masm, ret_type, stack_slots); | 2001 save_native_result(masm, ret_type, stack_slots); |
1659 __ mov(c_rarg0, r15_thread); | 2002 __ mov(c_rarg0, r15_thread); |
1660 __ mov(r12, rsp); // remember sp | 2003 __ mov(r12, rsp); // remember sp |
1661 __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows | 2004 __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows |
1662 __ andptr(rsp, -16); // align stack as required by ABI | 2005 __ andptr(rsp, -16); // align stack as required by ABI |
1663 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans))); | 2006 if (!is_critical_native) { |
2007 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans))); | |
2008 } else { | |
2009 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans_and_transition))); | |
2010 } | |
1664 __ mov(rsp, r12); // restore sp | 2011 __ mov(rsp, r12); // restore sp |
1665 __ reinit_heapbase(); | 2012 __ reinit_heapbase(); |
1666 // Restore any method result value | 2013 // Restore any method result value |
1667 restore_native_result(masm, ret_type, stack_slots); | 2014 restore_native_result(masm, ret_type, stack_slots); |
2015 | |
2016 if (is_critical_native) { | |
2017 // The call above performed the transition to thread_in_Java so | |
2018 // skip the transition logic below. | |
2019 __ jmpb(after_transition); | |
2020 } | |
2021 | |
1668 __ bind(Continue); | 2022 __ bind(Continue); |
1669 } | 2023 } |
1670 | 2024 |
1671 // change thread state | 2025 // change thread state |
1672 __ movl(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_Java); | 2026 __ movl(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_Java); |
2027 __ bind(after_transition); | |
1673 | 2028 |
1674 Label reguard; | 2029 Label reguard; |
1675 Label reguard_done; | 2030 Label reguard_done; |
1676 __ cmpl(Address(r15_thread, JavaThread::stack_guard_state_offset()), JavaThread::stack_guard_yellow_disabled); | 2031 __ cmpl(Address(r15_thread, JavaThread::stack_guard_state_offset()), JavaThread::stack_guard_yellow_disabled); |
1677 __ jcc(Assembler::equal, reguard); | 2032 __ jcc(Assembler::equal, reguard); |
1745 __ movptr(rax, Address(rax, 0)); | 2100 __ movptr(rax, Address(rax, 0)); |
1746 __ bind(L); | 2101 __ bind(L); |
1747 __ verify_oop(rax); | 2102 __ verify_oop(rax); |
1748 } | 2103 } |
1749 | 2104 |
1750 // reset handle block | 2105 if (!is_critical_native) { |
1751 __ movptr(rcx, Address(r15_thread, JavaThread::active_handles_offset())); | 2106 // reset handle block |
1752 __ movptr(Address(rcx, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD); | 2107 __ movptr(rcx, Address(r15_thread, JavaThread::active_handles_offset())); |
2108 __ movptr(Address(rcx, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD); | |
2109 } | |
1753 | 2110 |
1754 // pop our frame | 2111 // pop our frame |
1755 | 2112 |
1756 __ leave(); | 2113 __ leave(); |
1757 | 2114 |
1758 // Any exception pending? | 2115 if (!is_critical_native) { |
1759 __ cmpptr(Address(r15_thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD); | 2116 // Any exception pending? |
1760 __ jcc(Assembler::notEqual, exception_pending); | 2117 __ cmpptr(Address(r15_thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD); |
2118 __ jcc(Assembler::notEqual, exception_pending); | |
2119 } | |
1761 | 2120 |
1762 // Return | 2121 // Return |
1763 | 2122 |
1764 __ ret(0); | 2123 __ ret(0); |
1765 | 2124 |
1766 // Unexpected paths are out of line and go here | 2125 // Unexpected paths are out of line and go here |
1767 | 2126 |
1768 // forward the exception | 2127 if (!is_critical_native) { |
1769 __ bind(exception_pending); | 2128 // forward the exception |
1770 | 2129 __ bind(exception_pending); |
1771 // and forward the exception | 2130 |
1772 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry())); | 2131 // and forward the exception |
1773 | 2132 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry())); |
2133 } | |
1774 | 2134 |
1775 // Slow path locking & unlocking | 2135 // Slow path locking & unlocking |
1776 if (method->is_synchronized()) { | 2136 if (method->is_synchronized()) { |
1777 | 2137 |
1778 // BEGIN Slow path lock | 2138 // BEGIN Slow path lock |
1875 frame_complete, | 2235 frame_complete, |
1876 stack_slots / VMRegImpl::slots_per_word, | 2236 stack_slots / VMRegImpl::slots_per_word, |
1877 (is_static ? in_ByteSize(klass_offset) : in_ByteSize(receiver_offset)), | 2237 (is_static ? in_ByteSize(klass_offset) : in_ByteSize(receiver_offset)), |
1878 in_ByteSize(lock_slot_offset*VMRegImpl::stack_slot_size), | 2238 in_ByteSize(lock_slot_offset*VMRegImpl::stack_slot_size), |
1879 oop_maps); | 2239 oop_maps); |
2240 | |
2241 if (is_critical_native) { | |
2242 nm->set_lazy_critical_native(true); | |
2243 } | |
2244 | |
1880 return nm; | 2245 return nm; |
1881 | 2246 |
1882 } | 2247 } |
1883 | 2248 |
1884 #ifdef HAVE_DTRACE_H | 2249 #ifdef HAVE_DTRACE_H |