501 __ popa(); |
501 __ popa(); |
502 __ bind(L); |
502 __ bind(L); |
503 } |
503 } |
504 |
504 |
505 |
505 |
506 // Helper function to put tags in interpreter stack. |
|
507 static void tag_stack(MacroAssembler *masm, const BasicType sig, int st_off) { |
|
508 if (TaggedStackInterpreter) { |
|
509 int tag_offset = st_off + Interpreter::expr_tag_offset_in_bytes(0); |
|
510 if (sig == T_OBJECT || sig == T_ARRAY) { |
|
511 __ movptr(Address(rsp, tag_offset), frame::TagReference); |
|
512 } else if (sig == T_LONG || sig == T_DOUBLE) { |
|
513 int next_tag_offset = st_off + Interpreter::expr_tag_offset_in_bytes(1); |
|
514 __ movptr(Address(rsp, next_tag_offset), frame::TagValue); |
|
515 __ movptr(Address(rsp, tag_offset), frame::TagValue); |
|
516 } else { |
|
517 __ movptr(Address(rsp, tag_offset), frame::TagValue); |
|
518 } |
|
519 } |
|
520 } |
|
521 |
|
522 // Double and long values with Tagged stacks are not contiguous. |
|
523 static void move_c2i_double(MacroAssembler *masm, XMMRegister r, int st_off) { |
506 static void move_c2i_double(MacroAssembler *masm, XMMRegister r, int st_off) { |
524 int next_off = st_off - Interpreter::stackElementSize(); |
507 int next_off = st_off - Interpreter::stackElementSize; |
525 if (TaggedStackInterpreter) { |
508 __ movdbl(Address(rsp, next_off), r); |
526 __ movdbl(Address(rsp, next_off), r); |
|
527 // Move top half up and put tag in the middle. |
|
528 __ movl(rdi, Address(rsp, next_off+wordSize)); |
|
529 __ movl(Address(rsp, st_off), rdi); |
|
530 tag_stack(masm, T_DOUBLE, next_off); |
|
531 } else { |
|
532 __ movdbl(Address(rsp, next_off), r); |
|
533 } |
|
534 } |
509 } |
535 |
510 |
536 static void gen_c2i_adapter(MacroAssembler *masm, |
511 static void gen_c2i_adapter(MacroAssembler *masm, |
537 int total_args_passed, |
512 int total_args_passed, |
538 int comp_args_on_stack, |
513 int comp_args_on_stack, |
558 #endif /* COMPILER2 */ |
533 #endif /* COMPILER2 */ |
559 |
534 |
560 // Since all args are passed on the stack, total_args_passed * interpreter_ |
535 // Since all args are passed on the stack, total_args_passed * interpreter_ |
561 // stack_element_size is the |
536 // stack_element_size is the |
562 // space we need. |
537 // space we need. |
563 int extraspace = total_args_passed * Interpreter::stackElementSize(); |
538 int extraspace = total_args_passed * Interpreter::stackElementSize; |
564 |
539 |
565 // Get return address |
540 // Get return address |
566 __ pop(rax); |
541 __ pop(rax); |
567 |
542 |
568 // set senderSP value |
543 // set senderSP value |
576 assert(i > 0 && (sig_bt[i-1] == T_LONG || sig_bt[i-1] == T_DOUBLE), "missing half"); |
551 assert(i > 0 && (sig_bt[i-1] == T_LONG || sig_bt[i-1] == T_DOUBLE), "missing half"); |
577 continue; |
552 continue; |
578 } |
553 } |
579 |
554 |
580 // st_off points to lowest address on stack. |
555 // st_off points to lowest address on stack. |
581 int st_off = ((total_args_passed - 1) - i) * Interpreter::stackElementSize(); |
556 int st_off = ((total_args_passed - 1) - i) * Interpreter::stackElementSize; |
582 int next_off = st_off - Interpreter::stackElementSize(); |
557 int next_off = st_off - Interpreter::stackElementSize; |
583 |
558 |
584 // Say 4 args: |
559 // Say 4 args: |
585 // i st_off |
560 // i st_off |
586 // 0 12 T_LONG |
561 // 0 12 T_LONG |
587 // 1 8 T_VOID |
562 // 1 8 T_VOID |
599 int ld_off = r_1->reg2stack() * VMRegImpl::stack_slot_size + extraspace; |
574 int ld_off = r_1->reg2stack() * VMRegImpl::stack_slot_size + extraspace; |
600 |
575 |
601 if (!r_2->is_valid()) { |
576 if (!r_2->is_valid()) { |
602 __ movl(rdi, Address(rsp, ld_off)); |
577 __ movl(rdi, Address(rsp, ld_off)); |
603 __ movptr(Address(rsp, st_off), rdi); |
578 __ movptr(Address(rsp, st_off), rdi); |
604 tag_stack(masm, sig_bt[i], st_off); |
|
605 } else { |
579 } else { |
606 |
580 |
607 // ld_off == LSW, ld_off+VMRegImpl::stack_slot_size == MSW |
581 // ld_off == LSW, ld_off+VMRegImpl::stack_slot_size == MSW |
608 // st_off == MSW, st_off-wordSize == LSW |
582 // st_off == MSW, st_off-wordSize == LSW |
609 |
583 |
617 // Overwrite the unused slot with known junk |
591 // Overwrite the unused slot with known junk |
618 __ mov64(rax, CONST64(0xdeadffffdeadaaaa)); |
592 __ mov64(rax, CONST64(0xdeadffffdeadaaaa)); |
619 __ movptr(Address(rsp, st_off), rax); |
593 __ movptr(Address(rsp, st_off), rax); |
620 #endif /* ASSERT */ |
594 #endif /* ASSERT */ |
621 #endif // _LP64 |
595 #endif // _LP64 |
622 tag_stack(masm, sig_bt[i], next_off); |
|
623 } |
596 } |
624 } else if (r_1->is_Register()) { |
597 } else if (r_1->is_Register()) { |
625 Register r = r_1->as_Register(); |
598 Register r = r_1->as_Register(); |
626 if (!r_2->is_valid()) { |
599 if (!r_2->is_valid()) { |
627 __ movl(Address(rsp, st_off), r); |
600 __ movl(Address(rsp, st_off), r); |
628 tag_stack(masm, sig_bt[i], st_off); |
|
629 } else { |
601 } else { |
630 // long/double in gpr |
602 // long/double in gpr |
631 NOT_LP64(ShouldNotReachHere()); |
603 NOT_LP64(ShouldNotReachHere()); |
632 // Two VMRegs can be T_OBJECT, T_ADDRESS, T_DOUBLE, T_LONG |
604 // Two VMRegs can be T_OBJECT, T_ADDRESS, T_DOUBLE, T_LONG |
633 // T_DOUBLE and T_LONG use two slots in the interpreter |
605 // T_DOUBLE and T_LONG use two slots in the interpreter |
637 // Overwrite the unused slot with known junk |
609 // Overwrite the unused slot with known junk |
638 LP64_ONLY(__ mov64(rax, CONST64(0xdeadffffdeadaaab))); |
610 LP64_ONLY(__ mov64(rax, CONST64(0xdeadffffdeadaaab))); |
639 __ movptr(Address(rsp, st_off), rax); |
611 __ movptr(Address(rsp, st_off), rax); |
640 #endif /* ASSERT */ |
612 #endif /* ASSERT */ |
641 __ movptr(Address(rsp, next_off), r); |
613 __ movptr(Address(rsp, next_off), r); |
642 tag_stack(masm, sig_bt[i], next_off); |
|
643 } else { |
614 } else { |
644 __ movptr(Address(rsp, st_off), r); |
615 __ movptr(Address(rsp, st_off), r); |
645 tag_stack(masm, sig_bt[i], st_off); |
|
646 } |
616 } |
647 } |
617 } |
648 } else { |
618 } else { |
649 assert(r_1->is_XMMRegister(), ""); |
619 assert(r_1->is_XMMRegister(), ""); |
650 if (!r_2->is_valid()) { |
620 if (!r_2->is_valid()) { |
651 __ movflt(Address(rsp, st_off), r_1->as_XMMRegister()); |
621 __ movflt(Address(rsp, st_off), r_1->as_XMMRegister()); |
652 tag_stack(masm, sig_bt[i], st_off); |
|
653 } else { |
622 } else { |
654 assert(sig_bt[i] == T_DOUBLE || sig_bt[i] == T_LONG, "wrong type"); |
623 assert(sig_bt[i] == T_DOUBLE || sig_bt[i] == T_LONG, "wrong type"); |
655 move_c2i_double(masm, r_1->as_XMMRegister(), st_off); |
624 move_c2i_double(masm, r_1->as_XMMRegister(), st_off); |
656 } |
625 } |
657 } |
626 } |
663 __ push(rax); |
632 __ push(rax); |
664 __ jmp(rcx); |
633 __ jmp(rcx); |
665 } |
634 } |
666 |
635 |
667 |
636 |
668 // For tagged stacks, double or long value aren't contiguous on the stack |
|
669 // so get them contiguous for the xmm load |
|
670 static void move_i2c_double(MacroAssembler *masm, XMMRegister r, Register saved_sp, int ld_off) { |
637 static void move_i2c_double(MacroAssembler *masm, XMMRegister r, Register saved_sp, int ld_off) { |
671 int next_val_off = ld_off - Interpreter::stackElementSize(); |
638 int next_val_off = ld_off - Interpreter::stackElementSize; |
672 if (TaggedStackInterpreter) { |
639 __ movdbl(r, Address(saved_sp, next_val_off)); |
673 // use tag slot temporarily for MSW |
|
674 __ movptr(rsi, Address(saved_sp, ld_off)); |
|
675 __ movptr(Address(saved_sp, next_val_off+wordSize), rsi); |
|
676 __ movdbl(r, Address(saved_sp, next_val_off)); |
|
677 // restore tag |
|
678 __ movptr(Address(saved_sp, next_val_off+wordSize), frame::TagValue); |
|
679 } else { |
|
680 __ movdbl(r, Address(saved_sp, next_val_off)); |
|
681 } |
|
682 } |
640 } |
683 |
641 |
684 static void gen_i2c_adapter(MacroAssembler *masm, |
642 static void gen_i2c_adapter(MacroAssembler *masm, |
685 int total_args_passed, |
643 int total_args_passed, |
686 int comp_args_on_stack, |
644 int comp_args_on_stack, |
795 // Pick up 0, 1 or 2 words from SP+offset. |
753 // Pick up 0, 1 or 2 words from SP+offset. |
796 |
754 |
797 assert(!regs[i].second()->is_valid() || regs[i].first()->next() == regs[i].second(), |
755 assert(!regs[i].second()->is_valid() || regs[i].first()->next() == regs[i].second(), |
798 "scrambled load targets?"); |
756 "scrambled load targets?"); |
799 // Load in argument order going down. |
757 // Load in argument order going down. |
800 int ld_off = (total_args_passed - i)*Interpreter::stackElementSize() + Interpreter::value_offset_in_bytes(); |
758 int ld_off = (total_args_passed - i) * Interpreter::stackElementSize; |
801 // Point to interpreter value (vs. tag) |
759 // Point to interpreter value (vs. tag) |
802 int next_off = ld_off - Interpreter::stackElementSize(); |
760 int next_off = ld_off - Interpreter::stackElementSize; |
803 // |
761 // |
804 // |
762 // |
805 // |
763 // |
806 VMReg r_1 = regs[i].first(); |
764 VMReg r_1 = regs[i].first(); |
807 VMReg r_2 = regs[i].second(); |
765 VMReg r_2 = regs[i].second(); |
2320 #endif // HAVE_DTRACE_H |
2278 #endif // HAVE_DTRACE_H |
2321 |
2279 |
2322 // this function returns the adjust size (in number of words) to a c2i adapter |
2280 // this function returns the adjust size (in number of words) to a c2i adapter |
2323 // activation for use during deoptimization |
2281 // activation for use during deoptimization |
2324 int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals ) { |
2282 int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals ) { |
2325 return (callee_locals - callee_parameters) * Interpreter::stackElementWords(); |
2283 return (callee_locals - callee_parameters) * Interpreter::stackElementWords; |
2326 } |
2284 } |
2327 |
2285 |
2328 |
2286 |
2329 uint SharedRuntime::out_preserve_stack_slots() { |
2287 uint SharedRuntime::out_preserve_stack_slots() { |
2330 return 0; |
2288 return 0; |