Mercurial > hg > graal-compiler
comparison src/cpu/sparc/vm/sharedRuntime_sparc.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 | 576e77447e3c |
children | c18cbe5936b8 61b2245abf36 |
comparison
equal
deleted
inserted
replaced
1505:0c5b3cf3c1f5 | 1506:2338d41fbd81 |
---|---|
545 MacroAssembler *masm; | 545 MacroAssembler *masm; |
546 Register Rdisp; | 546 Register Rdisp; |
547 void set_Rdisp(Register r) { Rdisp = r; } | 547 void set_Rdisp(Register r) { Rdisp = r; } |
548 | 548 |
549 void patch_callers_callsite(); | 549 void patch_callers_callsite(); |
550 void tag_c2i_arg(frame::Tag t, Register base, int st_off, Register scratch); | |
551 | 550 |
552 // base+st_off points to top of argument | 551 // base+st_off points to top of argument |
553 int arg_offset(const int st_off) { return st_off + Interpreter::value_offset_in_bytes(); } | 552 int arg_offset(const int st_off) { return st_off; } |
554 int next_arg_offset(const int st_off) { | 553 int next_arg_offset(const int st_off) { |
555 return st_off - Interpreter::stackElementSize() + Interpreter::value_offset_in_bytes(); | 554 return st_off - Interpreter::stackElementSize; |
556 } | |
557 | |
558 int tag_offset(const int st_off) { return st_off + Interpreter::tag_offset_in_bytes(); } | |
559 int next_tag_offset(const int st_off) { | |
560 return st_off - Interpreter::stackElementSize() + Interpreter::tag_offset_in_bytes(); | |
561 } | 555 } |
562 | 556 |
563 // Argument slot values may be loaded first into a register because | 557 // Argument slot values may be loaded first into a register because |
564 // they might not fit into displacement. | 558 // they might not fit into displacement. |
565 RegisterOrConstant arg_slot(const int st_off); | 559 RegisterOrConstant arg_slot(const int st_off); |
566 RegisterOrConstant next_arg_slot(const int st_off); | 560 RegisterOrConstant next_arg_slot(const int st_off); |
567 | |
568 RegisterOrConstant tag_slot(const int st_off); | |
569 RegisterOrConstant next_tag_slot(const int st_off); | |
570 | 561 |
571 // Stores long into offset pointed to by base | 562 // Stores long into offset pointed to by base |
572 void store_c2i_long(Register r, Register base, | 563 void store_c2i_long(Register r, Register base, |
573 const int st_off, bool is_stack); | 564 const int st_off, bool is_stack); |
574 void store_c2i_object(Register r, Register base, | 565 void store_c2i_object(Register r, Register base, |
651 | 642 |
652 __ restore(); // Restore args | 643 __ restore(); // Restore args |
653 __ bind(L); | 644 __ bind(L); |
654 } | 645 } |
655 | 646 |
656 void AdapterGenerator::tag_c2i_arg(frame::Tag t, Register base, int st_off, | |
657 Register scratch) { | |
658 if (TaggedStackInterpreter) { | |
659 RegisterOrConstant slot = tag_slot(st_off); | |
660 // have to store zero because local slots can be reused (rats!) | |
661 if (t == frame::TagValue) { | |
662 __ st_ptr(G0, base, slot); | |
663 } else if (t == frame::TagCategory2) { | |
664 __ st_ptr(G0, base, slot); | |
665 __ st_ptr(G0, base, next_tag_slot(st_off)); | |
666 } else { | |
667 __ mov(t, scratch); | |
668 __ st_ptr(scratch, base, slot); | |
669 } | |
670 } | |
671 } | |
672 | |
673 | 647 |
674 RegisterOrConstant AdapterGenerator::arg_slot(const int st_off) { | 648 RegisterOrConstant AdapterGenerator::arg_slot(const int st_off) { |
675 RegisterOrConstant roc(arg_offset(st_off)); | 649 RegisterOrConstant roc(arg_offset(st_off)); |
676 return __ ensure_simm13_or_reg(roc, Rdisp); | 650 return __ ensure_simm13_or_reg(roc, Rdisp); |
677 } | 651 } |
678 | 652 |
679 RegisterOrConstant AdapterGenerator::next_arg_slot(const int st_off) { | 653 RegisterOrConstant AdapterGenerator::next_arg_slot(const int st_off) { |
680 RegisterOrConstant roc(next_arg_offset(st_off)); | 654 RegisterOrConstant roc(next_arg_offset(st_off)); |
681 return __ ensure_simm13_or_reg(roc, Rdisp); | |
682 } | |
683 | |
684 | |
685 RegisterOrConstant AdapterGenerator::tag_slot(const int st_off) { | |
686 RegisterOrConstant roc(tag_offset(st_off)); | |
687 return __ ensure_simm13_or_reg(roc, Rdisp); | |
688 } | |
689 | |
690 RegisterOrConstant AdapterGenerator::next_tag_slot(const int st_off) { | |
691 RegisterOrConstant roc(next_tag_offset(st_off)); | |
692 return __ ensure_simm13_or_reg(roc, Rdisp); | 655 return __ ensure_simm13_or_reg(roc, Rdisp); |
693 } | 656 } |
694 | 657 |
695 | 658 |
696 // Stores long into offset pointed to by base | 659 // Stores long into offset pointed to by base |
716 __ stw(r->successor(), base, arg_slot(st_off) ); // lo bits | 679 __ stw(r->successor(), base, arg_slot(st_off) ); // lo bits |
717 __ stw(r , base, next_arg_slot(st_off)); // hi bits | 680 __ stw(r , base, next_arg_slot(st_off)); // hi bits |
718 } | 681 } |
719 #endif // COMPILER2 | 682 #endif // COMPILER2 |
720 #endif // _LP64 | 683 #endif // _LP64 |
721 tag_c2i_arg(frame::TagCategory2, base, st_off, r); | |
722 } | 684 } |
723 | 685 |
724 void AdapterGenerator::store_c2i_object(Register r, Register base, | 686 void AdapterGenerator::store_c2i_object(Register r, Register base, |
725 const int st_off) { | 687 const int st_off) { |
726 __ st_ptr (r, base, arg_slot(st_off)); | 688 __ st_ptr (r, base, arg_slot(st_off)); |
727 tag_c2i_arg(frame::TagReference, base, st_off, r); | |
728 } | 689 } |
729 | 690 |
730 void AdapterGenerator::store_c2i_int(Register r, Register base, | 691 void AdapterGenerator::store_c2i_int(Register r, Register base, |
731 const int st_off) { | 692 const int st_off) { |
732 __ st (r, base, arg_slot(st_off)); | 693 __ st (r, base, arg_slot(st_off)); |
733 tag_c2i_arg(frame::TagValue, base, st_off, r); | |
734 } | 694 } |
735 | 695 |
736 // Stores into offset pointed to by base | 696 // Stores into offset pointed to by base |
737 void AdapterGenerator::store_c2i_double(VMReg r_2, | 697 void AdapterGenerator::store_c2i_double(VMReg r_2, |
738 VMReg r_1, Register base, const int st_off) { | 698 VMReg r_1, Register base, const int st_off) { |
743 #else | 703 #else |
744 // Need to marshal 64-bit value from misaligned Lesp loads | 704 // Need to marshal 64-bit value from misaligned Lesp loads |
745 __ stf(FloatRegisterImpl::S, r_1->as_FloatRegister(), base, next_arg_slot(st_off)); | 705 __ stf(FloatRegisterImpl::S, r_1->as_FloatRegister(), base, next_arg_slot(st_off)); |
746 __ stf(FloatRegisterImpl::S, r_2->as_FloatRegister(), base, arg_slot(st_off) ); | 706 __ stf(FloatRegisterImpl::S, r_2->as_FloatRegister(), base, arg_slot(st_off) ); |
747 #endif | 707 #endif |
748 tag_c2i_arg(frame::TagCategory2, base, st_off, G1_scratch); | |
749 } | 708 } |
750 | 709 |
751 void AdapterGenerator::store_c2i_float(FloatRegister f, Register base, | 710 void AdapterGenerator::store_c2i_float(FloatRegister f, Register base, |
752 const int st_off) { | 711 const int st_off) { |
753 __ stf(FloatRegisterImpl::S, f, base, arg_slot(st_off)); | 712 __ stf(FloatRegisterImpl::S, f, base, arg_slot(st_off)); |
754 tag_c2i_arg(frame::TagValue, base, st_off, G1_scratch); | |
755 } | 713 } |
756 | 714 |
757 void AdapterGenerator::gen_c2i_adapter( | 715 void AdapterGenerator::gen_c2i_adapter( |
758 int total_args_passed, | 716 int total_args_passed, |
759 // VMReg max_arg, | 717 // VMReg max_arg, |
784 __ bind(skip_fixup); | 742 __ bind(skip_fixup); |
785 | 743 |
786 // Since all args are passed on the stack, total_args_passed*wordSize is the | 744 // Since all args are passed on the stack, total_args_passed*wordSize is the |
787 // space we need. Add in varargs area needed by the interpreter. Round up | 745 // space we need. Add in varargs area needed by the interpreter. Round up |
788 // to stack alignment. | 746 // to stack alignment. |
789 const int arg_size = total_args_passed * Interpreter::stackElementSize(); | 747 const int arg_size = total_args_passed * Interpreter::stackElementSize; |
790 const int varargs_area = | 748 const int varargs_area = |
791 (frame::varargs_offset - frame::register_save_words)*wordSize; | 749 (frame::varargs_offset - frame::register_save_words)*wordSize; |
792 const int extraspace = round_to(arg_size + varargs_area, 2*wordSize); | 750 const int extraspace = round_to(arg_size + varargs_area, 2*wordSize); |
793 | 751 |
794 int bias = STACK_BIAS; | 752 int bias = STACK_BIAS; |
795 const int interp_arg_offset = frame::varargs_offset*wordSize + | 753 const int interp_arg_offset = frame::varargs_offset*wordSize + |
796 (total_args_passed-1)*Interpreter::stackElementSize(); | 754 (total_args_passed-1)*Interpreter::stackElementSize; |
797 | 755 |
798 Register base = SP; | 756 Register base = SP; |
799 | 757 |
800 #ifdef _LP64 | 758 #ifdef _LP64 |
801 // In the 64bit build because of wider slots and STACKBIAS we can run | 759 // In the 64bit build because of wider slots and STACKBIAS we can run |
812 __ sub(SP, extraspace, SP); | 770 __ sub(SP, extraspace, SP); |
813 #endif // _LP64 | 771 #endif // _LP64 |
814 | 772 |
815 // First write G1 (if used) to where ever it must go | 773 // First write G1 (if used) to where ever it must go |
816 for (int i=0; i<total_args_passed; i++) { | 774 for (int i=0; i<total_args_passed; i++) { |
817 const int st_off = interp_arg_offset - (i*Interpreter::stackElementSize()) + bias; | 775 const int st_off = interp_arg_offset - (i*Interpreter::stackElementSize) + bias; |
818 VMReg r_1 = regs[i].first(); | 776 VMReg r_1 = regs[i].first(); |
819 VMReg r_2 = regs[i].second(); | 777 VMReg r_2 = regs[i].second(); |
820 if (r_1 == G1_scratch->as_VMReg()) { | 778 if (r_1 == G1_scratch->as_VMReg()) { |
821 if (sig_bt[i] == T_OBJECT || sig_bt[i] == T_ARRAY) { | 779 if (sig_bt[i] == T_OBJECT || sig_bt[i] == T_ARRAY) { |
822 store_c2i_object(G1_scratch, base, st_off); | 780 store_c2i_object(G1_scratch, base, st_off); |
829 } | 787 } |
830 } | 788 } |
831 | 789 |
832 // Now write the args into the outgoing interpreter space | 790 // Now write the args into the outgoing interpreter space |
833 for (int i=0; i<total_args_passed; i++) { | 791 for (int i=0; i<total_args_passed; i++) { |
834 const int st_off = interp_arg_offset - (i*Interpreter::stackElementSize()) + bias; | 792 const int st_off = interp_arg_offset - (i*Interpreter::stackElementSize) + bias; |
835 VMReg r_1 = regs[i].first(); | 793 VMReg r_1 = regs[i].first(); |
836 VMReg r_2 = regs[i].second(); | 794 VMReg r_2 = regs[i].second(); |
837 if (!r_1->is_valid()) { | 795 if (!r_1->is_valid()) { |
838 assert(!r_2->is_valid(), ""); | 796 assert(!r_2->is_valid(), ""); |
839 continue; | 797 continue; |
898 // The interpreter will restore SP to this value before returning. | 856 // The interpreter will restore SP to this value before returning. |
899 __ add(SP, extraspace, O5_savedSP); | 857 __ add(SP, extraspace, O5_savedSP); |
900 #endif // _LP64 | 858 #endif // _LP64 |
901 | 859 |
902 __ mov((frame::varargs_offset)*wordSize - | 860 __ mov((frame::varargs_offset)*wordSize - |
903 1*Interpreter::stackElementSize()+bias+BytesPerWord, G1); | 861 1*Interpreter::stackElementSize+bias+BytesPerWord, G1); |
904 // Jump to the interpreter just as if interpreter was doing it. | 862 // Jump to the interpreter just as if interpreter was doing it. |
905 __ jmpl(G3_scratch, 0, G0); | 863 __ jmpl(G3_scratch, 0, G0); |
906 // Setup Lesp for the call. Cannot actually set Lesp as the current Lesp | 864 // Setup Lesp for the call. Cannot actually set Lesp as the current Lesp |
907 // (really L0) is in use by the compiled frame as a generic temp. However, | 865 // (really L0) is in use by the compiled frame as a generic temp. However, |
908 // the interpreter does not know where its args are without some kind of | 866 // the interpreter does not know where its args are without some kind of |
1049 // Pick up 0, 1 or 2 words from Lesp+offset. Assume mis-aligned in the | 1007 // Pick up 0, 1 or 2 words from Lesp+offset. Assume mis-aligned in the |
1050 // 32-bit build and aligned in the 64-bit build. Look for the obvious | 1008 // 32-bit build and aligned in the 64-bit build. Look for the obvious |
1051 // ldx/lddf optimizations. | 1009 // ldx/lddf optimizations. |
1052 | 1010 |
1053 // Load in argument order going down. | 1011 // Load in argument order going down. |
1054 const int ld_off = (total_args_passed-i)*Interpreter::stackElementSize(); | 1012 const int ld_off = (total_args_passed-i)*Interpreter::stackElementSize; |
1055 set_Rdisp(G1_scratch); | 1013 set_Rdisp(G1_scratch); |
1056 | 1014 |
1057 VMReg r_1 = regs[i].first(); | 1015 VMReg r_1 = regs[i].first(); |
1058 VMReg r_2 = regs[i].second(); | 1016 VMReg r_2 = regs[i].second(); |
1059 if (!r_1->is_valid()) { | 1017 if (!r_1->is_valid()) { |
1118 bool g4_crushed = false; | 1076 bool g4_crushed = false; |
1119 bool g3_crushed = false; | 1077 bool g3_crushed = false; |
1120 for (int i=0; i<total_args_passed; i++) { | 1078 for (int i=0; i<total_args_passed; i++) { |
1121 if (regs[i].first()->is_Register() && regs[i].second()->is_valid()) { | 1079 if (regs[i].first()->is_Register() && regs[i].second()->is_valid()) { |
1122 // Load in argument order going down | 1080 // Load in argument order going down |
1123 int ld_off = (total_args_passed-i)*Interpreter::stackElementSize(); | 1081 int ld_off = (total_args_passed-i)*Interpreter::stackElementSize; |
1124 // Need to marshal 64-bit value from misaligned Lesp loads | 1082 // Need to marshal 64-bit value from misaligned Lesp loads |
1125 Register r = regs[i].first()->as_Register()->after_restore(); | 1083 Register r = regs[i].first()->as_Register()->after_restore(); |
1126 if (r == G1 || r == G4) { | 1084 if (r == G1 || r == G4) { |
1127 assert(!g4_crushed, "ordering problem"); | 1085 assert(!g4_crushed, "ordering problem"); |
1128 if (r == G4){ | 1086 if (r == G4){ |
3060 int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals) { | 3018 int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals) { |
3061 assert(callee_locals >= callee_parameters, | 3019 assert(callee_locals >= callee_parameters, |
3062 "test and remove; got more parms than locals"); | 3020 "test and remove; got more parms than locals"); |
3063 if (callee_locals < callee_parameters) | 3021 if (callee_locals < callee_parameters) |
3064 return 0; // No adjustment for negative locals | 3022 return 0; // No adjustment for negative locals |
3065 int diff = (callee_locals - callee_parameters) * Interpreter::stackElementWords(); | 3023 int diff = (callee_locals - callee_parameters) * Interpreter::stackElementWords; |
3066 return round_to(diff, WordsPerLong); | 3024 return round_to(diff, WordsPerLong); |
3067 } | 3025 } |
3068 | 3026 |
3069 // "Top of Stack" slots that may be unused by the calling convention but must | 3027 // "Top of Stack" slots that may be unused by the calling convention but must |
3070 // otherwise be preserved. | 3028 // otherwise be preserved. |