Mercurial > hg > graal-compiler
comparison src/cpu/x86/vm/sharedRuntime_x86_32.cpp @ 6275:957c266d8bc5
Merge with http://hg.openjdk.java.net/hsx/hsx24/hotspot/
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Tue, 21 Aug 2012 10:39:19 +0200 |
parents | 1d7922586cf6 |
children | e4ae9932c292 da91efe96a93 |
comparison
equal
deleted
inserted
replaced
5891:fd8832ae511d | 6275:957c266d8bc5 |
---|---|
641 static void move_i2c_double(MacroAssembler *masm, XMMRegister r, Register saved_sp, int ld_off) { | 641 static void move_i2c_double(MacroAssembler *masm, XMMRegister r, Register saved_sp, int ld_off) { |
642 int next_val_off = ld_off - Interpreter::stackElementSize; | 642 int next_val_off = ld_off - Interpreter::stackElementSize; |
643 __ movdbl(r, Address(saved_sp, next_val_off)); | 643 __ movdbl(r, Address(saved_sp, next_val_off)); |
644 } | 644 } |
645 | 645 |
646 static void range_check(MacroAssembler* masm, Register pc_reg, Register temp_reg, | |
647 address code_start, address code_end, | |
648 Label& L_ok) { | |
649 Label L_fail; | |
650 __ lea(temp_reg, ExternalAddress(code_start)); | |
651 __ cmpptr(pc_reg, temp_reg); | |
652 __ jcc(Assembler::belowEqual, L_fail); | |
653 __ lea(temp_reg, ExternalAddress(code_end)); | |
654 __ cmpptr(pc_reg, temp_reg); | |
655 __ jcc(Assembler::below, L_ok); | |
656 __ bind(L_fail); | |
657 } | |
658 | |
646 static void gen_i2c_adapter(MacroAssembler *masm, | 659 static void gen_i2c_adapter(MacroAssembler *masm, |
647 int total_args_passed, | 660 int total_args_passed, |
648 int comp_args_on_stack, | 661 int comp_args_on_stack, |
649 const BasicType *sig_bt, | 662 const BasicType *sig_bt, |
650 const VMRegPair *regs) { | 663 const VMRegPair *regs) { |
651 | 664 |
652 // Note: rsi contains the senderSP on entry. We must preserve it since | 665 // Note: rsi contains the senderSP on entry. We must preserve it since |
653 // we may do a i2c -> c2i transition if we lose a race where compiled | 666 // we may do a i2c -> c2i transition if we lose a race where compiled |
654 // code goes non-entrant while we get args ready. | 667 // code goes non-entrant while we get args ready. |
655 | 668 |
669 // Adapters can be frameless because they do not require the caller | |
670 // to perform additional cleanup work, such as correcting the stack pointer. | |
671 // An i2c adapter is frameless because the *caller* frame, which is interpreted, | |
672 // routinely repairs its own stack pointer (from interpreter_frame_last_sp), | |
673 // even if a callee has modified the stack pointer. | |
674 // A c2i adapter is frameless because the *callee* frame, which is interpreted, | |
675 // routinely repairs its caller's stack pointer (from sender_sp, which is set | |
676 // up via the senderSP register). | |
677 // In other words, if *either* the caller or callee is interpreted, we can | |
678 // get the stack pointer repaired after a call. | |
679 // This is why c2i and i2c adapters cannot be indefinitely composed. | |
680 // In particular, if a c2i adapter were to somehow call an i2c adapter, | |
681 // both caller and callee would be compiled methods, and neither would | |
682 // clean up the stack pointer changes performed by the two adapters. | |
683 // If this happens, control eventually transfers back to the compiled | |
684 // caller, but with an uncorrected stack, causing delayed havoc. | |
685 | |
656 // Pick up the return address | 686 // Pick up the return address |
657 __ movptr(rax, Address(rsp, 0)); | 687 __ movptr(rax, Address(rsp, 0)); |
688 | |
689 if (VerifyAdapterCalls && | |
690 (Interpreter::code() != NULL || StubRoutines::code1() != NULL)) { | |
691 // So, let's test for cascading c2i/i2c adapters right now. | |
692 // assert(Interpreter::contains($return_addr) || | |
693 // StubRoutines::contains($return_addr), | |
694 // "i2c adapter must return to an interpreter frame"); | |
695 __ block_comment("verify_i2c { "); | |
696 Label L_ok; | |
697 if (Interpreter::code() != NULL) | |
698 range_check(masm, rax, rdi, | |
699 Interpreter::code()->code_start(), Interpreter::code()->code_end(), | |
700 L_ok); | |
701 if (StubRoutines::code1() != NULL) | |
702 range_check(masm, rax, rdi, | |
703 StubRoutines::code1()->code_begin(), StubRoutines::code1()->code_end(), | |
704 L_ok); | |
705 if (StubRoutines::code2() != NULL) | |
706 range_check(masm, rax, rdi, | |
707 StubRoutines::code2()->code_begin(), StubRoutines::code2()->code_end(), | |
708 L_ok); | |
709 const char* msg = "i2c adapter must return to an interpreter frame"; | |
710 __ block_comment(msg); | |
711 __ stop(msg); | |
712 __ bind(L_ok); | |
713 __ block_comment("} verify_i2ce "); | |
714 } | |
658 | 715 |
659 // Must preserve original SP for loading incoming arguments because | 716 // Must preserve original SP for loading incoming arguments because |
660 // we need to align the outgoing SP for compiled code. | 717 // we need to align the outgoing SP for compiled code. |
661 __ movptr(rdi, rsp); | 718 __ movptr(rdi, rsp); |
662 | 719 |
1291 simple_move32(masm, tmp, body_arg); | 1348 simple_move32(masm, tmp, body_arg); |
1292 simple_move32(masm, tmp, length_arg); | 1349 simple_move32(masm, tmp, length_arg); |
1293 __ bind(done); | 1350 __ bind(done); |
1294 } | 1351 } |
1295 | 1352 |
1353 static void verify_oop_args(MacroAssembler* masm, | |
1354 int total_args_passed, | |
1355 const BasicType* sig_bt, | |
1356 const VMRegPair* regs) { | |
1357 Register temp_reg = rbx; // not part of any compiled calling seq | |
1358 if (VerifyOops) { | |
1359 for (int i = 0; i < total_args_passed; i++) { | |
1360 if (sig_bt[i] == T_OBJECT || | |
1361 sig_bt[i] == T_ARRAY) { | |
1362 VMReg r = regs[i].first(); | |
1363 assert(r->is_valid(), "bad oop arg"); | |
1364 if (r->is_stack()) { | |
1365 __ movptr(temp_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize)); | |
1366 __ verify_oop(temp_reg); | |
1367 } else { | |
1368 __ verify_oop(r->as_Register()); | |
1369 } | |
1370 } | |
1371 } | |
1372 } | |
1373 } | |
1374 | |
1375 static void gen_special_dispatch(MacroAssembler* masm, | |
1376 int total_args_passed, | |
1377 int comp_args_on_stack, | |
1378 vmIntrinsics::ID special_dispatch, | |
1379 const BasicType* sig_bt, | |
1380 const VMRegPair* regs) { | |
1381 verify_oop_args(masm, total_args_passed, sig_bt, regs); | |
1382 | |
1383 // Now write the args into the outgoing interpreter space | |
1384 bool has_receiver = false; | |
1385 Register receiver_reg = noreg; | |
1386 int member_arg_pos = -1; | |
1387 Register member_reg = noreg; | |
1388 int ref_kind = MethodHandles::signature_polymorphic_intrinsic_ref_kind(special_dispatch); | |
1389 if (ref_kind != 0) { | |
1390 member_arg_pos = total_args_passed - 1; // trailing MemberName argument | |
1391 member_reg = rbx; // known to be free at this point | |
1392 has_receiver = MethodHandles::ref_kind_has_receiver(ref_kind); | |
1393 } else if (special_dispatch == vmIntrinsics::_invokeBasic) { | |
1394 has_receiver = true; | |
1395 } else { | |
1396 guarantee(false, err_msg("special_dispatch=%d", special_dispatch)); | |
1397 } | |
1398 | |
1399 if (member_reg != noreg) { | |
1400 // Load the member_arg into register, if necessary. | |
1401 assert(member_arg_pos >= 0 && member_arg_pos < total_args_passed, "oob"); | |
1402 assert(sig_bt[member_arg_pos] == T_OBJECT, "dispatch argument must be an object"); | |
1403 VMReg r = regs[member_arg_pos].first(); | |
1404 assert(r->is_valid(), "bad member arg"); | |
1405 if (r->is_stack()) { | |
1406 __ movptr(member_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize)); | |
1407 } else { | |
1408 // no data motion is needed | |
1409 member_reg = r->as_Register(); | |
1410 } | |
1411 } | |
1412 | |
1413 if (has_receiver) { | |
1414 // Make sure the receiver is loaded into a register. | |
1415 assert(total_args_passed > 0, "oob"); | |
1416 assert(sig_bt[0] == T_OBJECT, "receiver argument must be an object"); | |
1417 VMReg r = regs[0].first(); | |
1418 assert(r->is_valid(), "bad receiver arg"); | |
1419 if (r->is_stack()) { | |
1420 // Porting note: This assumes that compiled calling conventions always | |
1421 // pass the receiver oop in a register. If this is not true on some | |
1422 // platform, pick a temp and load the receiver from stack. | |
1423 assert(false, "receiver always in a register"); | |
1424 receiver_reg = rcx; // known to be free at this point | |
1425 __ movptr(receiver_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize)); | |
1426 } else { | |
1427 // no data motion is needed | |
1428 receiver_reg = r->as_Register(); | |
1429 } | |
1430 } | |
1431 | |
1432 // Figure out which address we are really jumping to: | |
1433 MethodHandles::generate_method_handle_dispatch(masm, special_dispatch, | |
1434 receiver_reg, member_reg, /*for_compiler_entry:*/ true); | |
1435 } | |
1296 | 1436 |
1297 // --------------------------------------------------------------------------- | 1437 // --------------------------------------------------------------------------- |
1298 // Generate a native wrapper for a given method. The method takes arguments | 1438 // Generate a native wrapper for a given method. The method takes arguments |
1299 // in the Java compiled code convention, marshals them to the native | 1439 // in the Java compiled code convention, marshals them to the native |
1300 // convention (handlizes oops, etc), transitions to native, makes the call, | 1440 // convention (handlizes oops, etc), transitions to native, makes the call, |
1321 // call into JVM and possible unlock the JNI critical | 1461 // call into JVM and possible unlock the JNI critical |
1322 // if a GC was suppressed while in the critical native. | 1462 // if a GC was suppressed while in the critical native. |
1323 // transition back to thread_in_Java | 1463 // transition back to thread_in_Java |
1324 // return to caller | 1464 // return to caller |
1325 // | 1465 // |
1326 nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, | 1466 nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm, |
1327 methodHandle method, | 1467 methodHandle method, |
1328 int compile_id, | 1468 int compile_id, |
1329 int total_in_args, | 1469 int total_in_args, |
1330 int comp_args_on_stack, | 1470 int comp_args_on_stack, |
1331 BasicType *in_sig_bt, | 1471 BasicType* in_sig_bt, |
1332 VMRegPair *in_regs, | 1472 VMRegPair* in_regs, |
1333 BasicType ret_type) { | 1473 BasicType ret_type) { |
1474 if (method->is_method_handle_intrinsic()) { | |
1475 vmIntrinsics::ID iid = method->intrinsic_id(); | |
1476 intptr_t start = (intptr_t)__ pc(); | |
1477 int vep_offset = ((intptr_t)__ pc()) - start; | |
1478 gen_special_dispatch(masm, | |
1479 total_in_args, | |
1480 comp_args_on_stack, | |
1481 method->intrinsic_id(), | |
1482 in_sig_bt, | |
1483 in_regs); | |
1484 int frame_complete = ((intptr_t)__ pc()) - start; // not complete, period | |
1485 __ flush(); | |
1486 int stack_slots = SharedRuntime::out_preserve_stack_slots(); // no out slots at all, actually | |
1487 return nmethod::new_native_nmethod(method, | |
1488 compile_id, | |
1489 masm->code(), | |
1490 vep_offset, | |
1491 frame_complete, | |
1492 stack_slots / VMRegImpl::slots_per_word, | |
1493 in_ByteSize(-1), | |
1494 in_ByteSize(-1), | |
1495 (OopMapSet*)NULL); | |
1496 } | |
1334 bool is_critical_native = true; | 1497 bool is_critical_native = true; |
1335 address native_func = method->critical_native_function(); | 1498 address native_func = method->critical_native_function(); |
1336 if (native_func == NULL) { | 1499 if (native_func == NULL) { |
1337 native_func = method->native_function(); | 1500 native_func = method->native_function(); |
1338 is_critical_native = false; | 1501 is_critical_native = false; |
1434 int single_slots = 0; | 1597 int single_slots = 0; |
1435 for ( int i = 0; i < total_in_args; i++) { | 1598 for ( int i = 0; i < total_in_args; i++) { |
1436 if (in_regs[i].first()->is_Register()) { | 1599 if (in_regs[i].first()->is_Register()) { |
1437 const Register reg = in_regs[i].first()->as_Register(); | 1600 const Register reg = in_regs[i].first()->as_Register(); |
1438 switch (in_sig_bt[i]) { | 1601 switch (in_sig_bt[i]) { |
1439 case T_ARRAY: | 1602 case T_ARRAY: // critical array (uses 2 slots on LP64) |
1440 case T_BOOLEAN: | 1603 case T_BOOLEAN: |
1441 case T_BYTE: | 1604 case T_BYTE: |
1442 case T_SHORT: | 1605 case T_SHORT: |
1443 case T_CHAR: | 1606 case T_CHAR: |
1444 case T_INT: single_slots++; break; | 1607 case T_INT: single_slots++; break; |