Mercurial > hg > truffle
comparison src/cpu/x86/vm/sharedRuntime_x86_32.cpp @ 1506:2338d41fbd81
6943304: remove tagged stack interpreter
Reviewed-by: coleenp, never, gbenson
author | twisti |
---|---|
date | Fri, 30 Apr 2010 08:37:24 -0700 |
parents | cf0685d550f1 |
children | c18cbe5936b8 |
comparison
equal
deleted
inserted
replaced
1505:0c5b3cf3c1f5 | 1506:2338d41fbd81 |
---|---|
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; |