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.