comparison src/cpu/sparc/vm/sharedRuntime_sparc.cpp @ 1006:dcf03e02b020

6879902: CTW failure jdk6_18/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp:845 Summary: For signatures with a large number of arguments the offset for the float store becomes too big and does not fit in 13-bit. Reviewed-by: kvn, never
author twisti
date Tue, 06 Oct 2009 02:11:49 -0700
parents 6b2273dd6fa9
children 1ce3281a8e93
comparison
equal deleted inserted replaced
997:46b819ba120b 1006:dcf03e02b020
538 // retun the amount of stack space these arguments will need. 538 // retun the amount of stack space these arguments will need.
539 return stk_reg_pairs; 539 return stk_reg_pairs;
540 540
541 } 541 }
542 542
543 // Helper class mostly to avoid passing masm everywhere, and handle store 543 // Helper class mostly to avoid passing masm everywhere, and handle
544 // displacement overflow logic for LP64 544 // store displacement overflow logic.
545 class AdapterGenerator { 545 class AdapterGenerator {
546 MacroAssembler *masm; 546 MacroAssembler *masm;
547 #ifdef _LP64
548 Register Rdisp; 547 Register Rdisp;
549 void set_Rdisp(Register r) { Rdisp = r; } 548 void set_Rdisp(Register r) { Rdisp = r; }
550 #endif // _LP64
551 549
552 void patch_callers_callsite(); 550 void patch_callers_callsite();
553 void tag_c2i_arg(frame::Tag t, Register base, int st_off, Register scratch); 551 void tag_c2i_arg(frame::Tag t, Register base, int st_off, Register scratch);
554 552
555 // base+st_off points to top of argument 553 // base+st_off points to top of argument
556 int arg_offset(const int st_off) { return st_off + Interpreter::value_offset_in_bytes(); } 554 int arg_offset(const int st_off) { return st_off + Interpreter::value_offset_in_bytes(); }
557 int next_arg_offset(const int st_off) { 555 int next_arg_offset(const int st_off) {
558 return st_off - Interpreter::stackElementSize() + Interpreter::value_offset_in_bytes(); 556 return st_off - Interpreter::stackElementSize() + Interpreter::value_offset_in_bytes();
559 } 557 }
560 558
561 #ifdef _LP64 559 int tag_offset(const int st_off) { return st_off + Interpreter::tag_offset_in_bytes(); }
562 // On _LP64 argument slot values are loaded first into a register 560 int next_tag_offset(const int st_off) {
563 // because they might not fit into displacement. 561 return st_off - Interpreter::stackElementSize() + Interpreter::tag_offset_in_bytes();
564 Register arg_slot(const int st_off); 562 }
565 Register next_arg_slot(const int st_off); 563
566 #else 564 // Argument slot values may be loaded first into a register because
567 int arg_slot(const int st_off) { return arg_offset(st_off); } 565 // they might not fit into displacement.
568 int next_arg_slot(const int st_off) { return next_arg_offset(st_off); } 566 RegisterOrConstant arg_slot(const int st_off);
569 #endif // _LP64 567 RegisterOrConstant next_arg_slot(const int st_off);
568
569 RegisterOrConstant tag_slot(const int st_off);
570 RegisterOrConstant next_tag_slot(const int st_off);
570 571
571 // Stores long into offset pointed to by base 572 // Stores long into offset pointed to by base
572 void store_c2i_long(Register r, Register base, 573 void store_c2i_long(Register r, Register base,
573 const int st_off, bool is_stack); 574 const int st_off, bool is_stack);
574 void store_c2i_object(Register r, Register base, 575 void store_c2i_object(Register r, Register base,
654 } 655 }
655 656
656 void AdapterGenerator::tag_c2i_arg(frame::Tag t, Register base, int st_off, 657 void AdapterGenerator::tag_c2i_arg(frame::Tag t, Register base, int st_off,
657 Register scratch) { 658 Register scratch) {
658 if (TaggedStackInterpreter) { 659 if (TaggedStackInterpreter) {
659 int tag_off = st_off + Interpreter::tag_offset_in_bytes(); 660 RegisterOrConstant slot = tag_slot(st_off);
660 #ifdef _LP64
661 Register tag_slot = Rdisp;
662 __ set(tag_off, tag_slot);
663 #else
664 int tag_slot = tag_off;
665 #endif // _LP64
666 // have to store zero because local slots can be reused (rats!) 661 // have to store zero because local slots can be reused (rats!)
667 if (t == frame::TagValue) { 662 if (t == frame::TagValue) {
668 __ st_ptr(G0, base, tag_slot); 663 __ st_ptr(G0, base, slot);
669 } else if (t == frame::TagCategory2) { 664 } else if (t == frame::TagCategory2) {
670 __ st_ptr(G0, base, tag_slot); 665 __ st_ptr(G0, base, slot);
671 int next_tag_off = st_off - Interpreter::stackElementSize() + 666 __ st_ptr(G0, base, next_tag_slot(st_off));
672 Interpreter::tag_offset_in_bytes();
673 #ifdef _LP64
674 __ set(next_tag_off, tag_slot);
675 #else
676 tag_slot = next_tag_off;
677 #endif // _LP64
678 __ st_ptr(G0, base, tag_slot);
679 } else { 667 } else {
680 __ mov(t, scratch); 668 __ mov(t, scratch);
681 __ st_ptr(scratch, base, tag_slot); 669 __ st_ptr(scratch, base, slot);
682 } 670 }
683 } 671 }
684 } 672 }
685 673
686 #ifdef _LP64 674
687 Register AdapterGenerator::arg_slot(const int st_off) { 675 RegisterOrConstant AdapterGenerator::arg_slot(const int st_off) {
688 __ set( arg_offset(st_off), Rdisp); 676 RegisterOrConstant roc(arg_offset(st_off));
689 return Rdisp; 677 return __ ensure_simm13_or_reg(roc, Rdisp);
690 } 678 }
691 679
692 Register AdapterGenerator::next_arg_slot(const int st_off){ 680 RegisterOrConstant AdapterGenerator::next_arg_slot(const int st_off) {
693 __ set( next_arg_offset(st_off), Rdisp); 681 RegisterOrConstant roc(next_arg_offset(st_off));
694 return Rdisp; 682 return __ ensure_simm13_or_reg(roc, Rdisp);
695 } 683 }
696 #endif // _LP64 684
685
686 RegisterOrConstant AdapterGenerator::tag_slot(const int st_off) {
687 RegisterOrConstant roc(tag_offset(st_off));
688 return __ ensure_simm13_or_reg(roc, Rdisp);
689 }
690
691 RegisterOrConstant AdapterGenerator::next_tag_slot(const int st_off) {
692 RegisterOrConstant roc(next_tag_offset(st_off));
693 return __ ensure_simm13_or_reg(roc, Rdisp);
694 }
695
697 696
698 // Stores long into offset pointed to by base 697 // Stores long into offset pointed to by base
699 void AdapterGenerator::store_c2i_long(Register r, Register base, 698 void AdapterGenerator::store_c2i_long(Register r, Register base,
700 const int st_off, bool is_stack) { 699 const int st_off, bool is_stack) {
701 #ifdef _LP64 700 #ifdef _LP64
1050 // 32-bit build and aligned in the 64-bit build. Look for the obvious 1049 // 32-bit build and aligned in the 64-bit build. Look for the obvious
1051 // ldx/lddf optimizations. 1050 // ldx/lddf optimizations.
1052 1051
1053 // Load in argument order going down. 1052 // Load in argument order going down.
1054 const int ld_off = (total_args_passed-i)*Interpreter::stackElementSize(); 1053 const int ld_off = (total_args_passed-i)*Interpreter::stackElementSize();
1055 #ifdef _LP64
1056 set_Rdisp(G1_scratch); 1054 set_Rdisp(G1_scratch);
1057 #endif // _LP64
1058 1055
1059 VMReg r_1 = regs[i].first(); 1056 VMReg r_1 = regs[i].first();
1060 VMReg r_2 = regs[i].second(); 1057 VMReg r_2 = regs[i].second();
1061 if (!r_1->is_valid()) { 1058 if (!r_1->is_valid()) {
1062 assert(!r_2->is_valid(), ""); 1059 assert(!r_2->is_valid(), "");
1072 __ ld(Gargs, arg_slot(ld_off), r); 1069 __ ld(Gargs, arg_slot(ld_off), r);
1073 } else { 1070 } else {
1074 #ifdef _LP64 1071 #ifdef _LP64
1075 // In V9, longs are given 2 64-bit slots in the interpreter, but the 1072 // In V9, longs are given 2 64-bit slots in the interpreter, but the
1076 // data is passed in only 1 slot. 1073 // data is passed in only 1 slot.
1077 Register slot = (sig_bt[i]==T_LONG) ? 1074 RegisterOrConstant slot = (sig_bt[i] == T_LONG) ?
1078 next_arg_slot(ld_off) : arg_slot(ld_off); 1075 next_arg_slot(ld_off) : arg_slot(ld_off);
1079 __ ldx(Gargs, slot, r); 1076 __ ldx(Gargs, slot, r);
1080 #else 1077 #else
1081 // Need to load a 64-bit value into G1/G4, but G1/G4 is being used in the 1078 // Need to load a 64-bit value into G1/G4, but G1/G4 is being used in the
1082 // stack shuffle. Load the first 2 longs into G1/G4 later. 1079 // stack shuffle. Load the first 2 longs into G1/G4 later.
1090 #ifdef _LP64 1087 #ifdef _LP64
1091 // In V9, doubles are given 2 64-bit slots in the interpreter, but the 1088 // In V9, doubles are given 2 64-bit slots in the interpreter, but the
1092 // data is passed in only 1 slot. This code also handles longs that 1089 // data is passed in only 1 slot. This code also handles longs that
1093 // are passed on the stack, but need a stack-to-stack move through a 1090 // are passed on the stack, but need a stack-to-stack move through a
1094 // spare float register. 1091 // spare float register.
1095 Register slot = (sig_bt[i]==T_LONG || sig_bt[i] == T_DOUBLE) ? 1092 RegisterOrConstant slot = (sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) ?
1096 next_arg_slot(ld_off) : arg_slot(ld_off); 1093 next_arg_slot(ld_off) : arg_slot(ld_off);
1097 __ ldf(FloatRegisterImpl::D, Gargs, slot, r_1->as_FloatRegister()); 1094 __ ldf(FloatRegisterImpl::D, Gargs, slot, r_1->as_FloatRegister());
1098 #else 1095 #else
1099 // Need to marshal 64-bit value from misaligned Lesp loads 1096 // Need to marshal 64-bit value from misaligned Lesp loads
1100 __ ldf(FloatRegisterImpl::S, Gargs, next_arg_slot(ld_off), r_1->as_FloatRegister()); 1097 __ ldf(FloatRegisterImpl::S, Gargs, next_arg_slot(ld_off), r_1->as_FloatRegister());
1107 if (regs[i].first()->is_stack()) { 1104 if (regs[i].first()->is_stack()) {
1108 assert(r_1->as_FloatRegister() == F8, "fix this code"); 1105 assert(r_1->as_FloatRegister() == F8, "fix this code");
1109 // Convert stack slot to an SP offset 1106 // Convert stack slot to an SP offset
1110 int st_off = reg2offset(regs[i].first()) + STACK_BIAS; 1107 int st_off = reg2offset(regs[i].first()) + STACK_BIAS;
1111 // Store down the shuffled stack word. Target address _is_ aligned. 1108 // Store down the shuffled stack word. Target address _is_ aligned.
1112 if (!r_2->is_valid()) __ stf(FloatRegisterImpl::S, r_1->as_FloatRegister(), SP, st_off); 1109 RegisterOrConstant slot = __ ensure_simm13_or_reg(st_off, Rdisp);
1113 else __ stf(FloatRegisterImpl::D, r_1->as_FloatRegister(), SP, st_off); 1110 if (!r_2->is_valid()) __ stf(FloatRegisterImpl::S, r_1->as_FloatRegister(), SP, slot);
1111 else __ stf(FloatRegisterImpl::D, r_1->as_FloatRegister(), SP, slot);
1114 } 1112 }
1115 } 1113 }
1116 bool made_space = false; 1114 bool made_space = false;
1117 #ifndef _LP64 1115 #ifndef _LP64
1118 // May need to pick up a few long args in G1/G4 1116 // May need to pick up a few long args in G1/G4