22 */
23
24 #include "precompiled.hpp"
25 #include "c1/c1_Defs.hpp"
26 #include "c1/c1_MacroAssembler.hpp"
27 #include "c1/c1_Runtime1.hpp"
28 #include "ci/ciUtilities.hpp"
29 #include "gc/shared/cardTable.hpp"
30 #include "gc/shared/cardTableBarrierSet.hpp"
31 #include "interpreter/interpreter.hpp"
32 #include "nativeInst_sparc.hpp"
33 #include "oops/compiledICHolder.hpp"
34 #include "oops/oop.inline.hpp"
35 #include "prims/jvmtiExport.hpp"
36 #include "runtime/sharedRuntime.hpp"
37 #include "runtime/signature.hpp"
38 #include "runtime/vframeArray.hpp"
39 #include "utilities/macros.hpp"
40 #include "utilities/align.hpp"
41 #include "vmreg_sparc.inline.hpp"
42 #if INCLUDE_ALL_GCS
43 #include "gc/g1/g1BarrierSet.hpp"
44 #include "gc/g1/g1CardTable.hpp"
45 #include "gc/g1/g1ThreadLocalData.hpp"
46 #endif
47
48 // Implementation of StubAssembler
49
50 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry_point, int number_of_arguments) {
51 // for sparc changing the number of arguments doesn't change
52 // anything about the frame size so we'll always lie and claim that
53 // we are only passing 1 argument.
54 set_num_rt_args(1);
55
56 assert_not_delayed();
57 // bang stack before going to runtime
58 set(-os::vm_page_size() + STACK_BIAS, G3_scratch);
59 st(G0, SP, G3_scratch);
60
61 // debugging support
62 assert(number_of_arguments >= 0 , "cannot have negative number of arguments");
63
64 set_last_Java_frame(SP, noreg);
65 if (VerifyThread) mov(G2_thread, O0); // about to be smashed; pass early
|
22 */
23
24 #include "precompiled.hpp"
25 #include "c1/c1_Defs.hpp"
26 #include "c1/c1_MacroAssembler.hpp"
27 #include "c1/c1_Runtime1.hpp"
28 #include "ci/ciUtilities.hpp"
29 #include "gc/shared/cardTable.hpp"
30 #include "gc/shared/cardTableBarrierSet.hpp"
31 #include "interpreter/interpreter.hpp"
32 #include "nativeInst_sparc.hpp"
33 #include "oops/compiledICHolder.hpp"
34 #include "oops/oop.inline.hpp"
35 #include "prims/jvmtiExport.hpp"
36 #include "runtime/sharedRuntime.hpp"
37 #include "runtime/signature.hpp"
38 #include "runtime/vframeArray.hpp"
39 #include "utilities/macros.hpp"
40 #include "utilities/align.hpp"
41 #include "vmreg_sparc.inline.hpp"
42
43 // Implementation of StubAssembler
44
45 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry_point, int number_of_arguments) {
46 // for sparc changing the number of arguments doesn't change
47 // anything about the frame size so we'll always lie and claim that
48 // we are only passing 1 argument.
49 set_num_rt_args(1);
50
51 assert_not_delayed();
52 // bang stack before going to runtime
53 set(-os::vm_page_size() + STACK_BIAS, G3_scratch);
54 st(G0, SP, G3_scratch);
55
56 // debugging support
57 assert(number_of_arguments >= 0 , "cannot have negative number of arguments");
58
59 set_last_Java_frame(SP, noreg);
60 if (VerifyThread) mov(G2_thread, O0); // about to be smashed; pass early
|
127 return call_RT(oop_result1, metadata_result, entry, 1);
128 }
129
130
131 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, Register arg1, Register arg2) {
132 // O0 is reserved for the thread
133 mov(arg1, O1);
134 mov(arg2, O2); assert(arg2 != O1, "smashed argument");
135 return call_RT(oop_result1, metadata_result, entry, 2);
136 }
137
138
139 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, Register arg1, Register arg2, Register arg3
140 // O0 is reserved for the thread
141 mov(arg1, O1);
142 mov(arg2, O2); assert(arg2 != O1, "smashed argument");
143 mov(arg3, O3); assert(arg3 != O1 && arg3 != O2, "smashed argument");
144 return call_RT(oop_result1, metadata_result, entry, 3);
145 }
146
147
148 // Implementation of Runtime1
149
150 #define __ sasm->
151
152 static int cpu_reg_save_offsets[FrameMap::nof_cpu_regs];
153 static int fpu_reg_save_offsets[FrameMap::nof_fpu_regs];
154 static int reg_save_size_in_words;
155 static int frame_size_in_bytes = -1;
156
157 static OopMap* generate_oop_map(StubAssembler* sasm, bool save_fpu_registers) {
158 assert(frame_size_in_bytes == __ total_frame_size_in_bytes(reg_save_size_in_words),
159 "mismatch in calculation");
160 sasm->set_frame_size(frame_size_in_bytes / BytesPerWord);
161 int frame_size_in_slots = frame_size_in_bytes / sizeof(jint);
162 OopMap* oop_map = new OopMap(frame_size_in_slots, 0);
163
164 int i;
165 for (i = 0; i < FrameMap::nof_cpu_regs; i++) {
166 Register r = as_Register(i);
167 if (r == G1 || r == G3 || r == G4 || r == G5) {
168 int sp_offset = cpu_reg_save_offsets[i];
169 oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset),
170 r->as_VMReg());
171 }
172 }
173
174 if (save_fpu_registers) {
175 for (i = 0; i < FrameMap::nof_fpu_regs; i++) {
176 FloatRegister r = as_FloatRegister(i);
177 int sp_offset = fpu_reg_save_offsets[i];
178 oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset),
179 r->as_VMReg());
180 }
181 }
182 return oop_map;
183 }
184
185 static OopMap* save_live_registers(StubAssembler* sasm, bool save_fpu_registers = true) {
186 assert(frame_size_in_bytes == __ total_frame_size_in_bytes(reg_save_size_in_words),
187 "mismatch in calculation");
188 __ save_frame_c1(frame_size_in_bytes);
189
190 // Record volatile registers as callee-save values in an OopMap so their save locations will be
191 // propagated to the caller frame's RegisterMap during StackFrameStream construction (needed for
192 // deoptimization; see compiledVFrame::create_stack_value). The caller's I, L and O registers
193 // are saved in register windows - I's and L's in the caller's frame and O's in the stub frame
194 // (as the stub's I's) when the runtime routine called by the stub creates its frame.
195 // OopMap frame sizes are in c2 stack slot sizes (sizeof(jint))
196
197 int i;
198 for (i = 0; i < FrameMap::nof_cpu_regs; i++) {
199 Register r = as_Register(i);
200 if (r == G1 || r == G3 || r == G4 || r == G5) {
201 int sp_offset = cpu_reg_save_offsets[i];
202 __ st_ptr(r, SP, (sp_offset * BytesPerWord) + STACK_BIAS);
203 }
204 }
205
206 if (save_fpu_registers) {
207 for (i = 0; i < FrameMap::nof_fpu_regs; i++) {
208 FloatRegister r = as_FloatRegister(i);
209 int sp_offset = fpu_reg_save_offsets[i];
210 __ stf(FloatRegisterImpl::S, r, SP, (sp_offset * BytesPerWord) + STACK_BIAS);
211 }
212 }
213
214 return generate_oop_map(sasm, save_fpu_registers);
215 }
216
217 static void restore_live_registers(StubAssembler* sasm, bool restore_fpu_registers = true) {
218 for (int i = 0; i < FrameMap::nof_cpu_regs; i++) {
219 Register r = as_Register(i);
220 if (r == G1 || r == G3 || r == G4 || r == G5) {
221 __ ld_ptr(SP, (cpu_reg_save_offsets[i] * BytesPerWord) + STACK_BIAS, r);
222 }
223 }
224
225 if (restore_fpu_registers) {
226 for (int i = 0; i < FrameMap::nof_fpu_regs; i++) {
227 FloatRegister r = as_FloatRegister(i);
228 __ ldf(FloatRegisterImpl::S, SP, (fpu_reg_save_offsets[i] * BytesPerWord) + STACK_BIAS, r);
229 }
230 }
231 }
232
233
234 void Runtime1::initialize_pd() {
235 // compute word offsets from SP at which live (non-windowed) registers are captured by stub routines
236 //
237 // A stub routine will have a frame that is at least large enough to hold
238 // a register window save area (obviously) and the volatile g registers
239 // and floating registers. A user of save_live_registers can have a frame
240 // that has more scratch area in it (although typically they will use L-regs).
241 // in that case the frame will look like this (stack growing down)
242 //
243 // FP -> | |
244 // | scratch mem |
245 // | " " |
246 // --------------
247 // | float regs |
248 // | " " |
249 // ---------------
250 // | G regs |
251 // | " " |
|
122 return call_RT(oop_result1, metadata_result, entry, 1);
123 }
124
125
126 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, Register arg1, Register arg2) {
127 // O0 is reserved for the thread
128 mov(arg1, O1);
129 mov(arg2, O2); assert(arg2 != O1, "smashed argument");
130 return call_RT(oop_result1, metadata_result, entry, 2);
131 }
132
133
134 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, Register arg1, Register arg2, Register arg3
135 // O0 is reserved for the thread
136 mov(arg1, O1);
137 mov(arg2, O2); assert(arg2 != O1, "smashed argument");
138 mov(arg3, O3); assert(arg3 != O1 && arg3 != O2, "smashed argument");
139 return call_RT(oop_result1, metadata_result, entry, 3);
140 }
141
142 void StubAssembler::prologue(const char* name, bool must_gc_arguments) {
143 set_info(name, must_gc_arguments);
144 }
145
146 void StubAssembler::epilogue() {
147 delayed()->restore();
148 }
149
150 // Implementation of Runtime1
151
152
153 static int cpu_reg_save_offsets[FrameMap::nof_cpu_regs];
154 static int fpu_reg_save_offsets[FrameMap::nof_fpu_regs];
155 static int reg_save_size_in_words;
156 static int frame_size_in_bytes = -1;
157
158 static OopMap* generate_oop_map(StubAssembler* sasm, bool save_fpu_registers) {
159 assert(frame_size_in_bytes == sasm->total_frame_size_in_bytes(reg_save_size_in_words),
160 "mismatch in calculation");
161 sasm->set_frame_size(frame_size_in_bytes / BytesPerWord);
162 int frame_size_in_slots = frame_size_in_bytes / sizeof(jint);
163 OopMap* oop_map = new OopMap(frame_size_in_slots, 0);
164
165 int i;
166 for (i = 0; i < FrameMap::nof_cpu_regs; i++) {
167 Register r = as_Register(i);
168 if (r == G1 || r == G3 || r == G4 || r == G5) {
169 int sp_offset = cpu_reg_save_offsets[i];
170 oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset),
171 r->as_VMReg());
172 }
173 }
174
175 if (save_fpu_registers) {
176 for (i = 0; i < FrameMap::nof_fpu_regs; i++) {
177 FloatRegister r = as_FloatRegister(i);
178 int sp_offset = fpu_reg_save_offsets[i];
179 oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset),
180 r->as_VMReg());
181 }
182 }
183 return oop_map;
184 }
185
186 #define __ this->
187
188 void C1_MacroAssembler::save_live_registers_no_oop_map(bool save_fpu_registers) {
189 assert(frame_size_in_bytes == __ total_frame_size_in_bytes(reg_save_size_in_words),
190 "mismatch in calculation");
191 __ save_frame_c1(frame_size_in_bytes);
192
193 // Record volatile registers as callee-save values in an OopMap so their save locations will be
194 // propagated to the caller frame's RegisterMap during StackFrameStream construction (needed for
195 // deoptimization; see compiledVFrame::create_stack_value). The caller's I, L and O registers
196 // are saved in register windows - I's and L's in the caller's frame and O's in the stub frame
197 // (as the stub's I's) when the runtime routine called by the stub creates its frame.
198 // OopMap frame sizes are in c2 stack slot sizes (sizeof(jint))
199
200 int i;
201 for (i = 0; i < FrameMap::nof_cpu_regs; i++) {
202 Register r = as_Register(i);
203 if (r == G1 || r == G3 || r == G4 || r == G5) {
204 int sp_offset = cpu_reg_save_offsets[i];
205 __ st_ptr(r, SP, (sp_offset * BytesPerWord) + STACK_BIAS);
206 }
207 }
208
209 if (save_fpu_registers) {
210 for (i = 0; i < FrameMap::nof_fpu_regs; i++) {
211 FloatRegister r = as_FloatRegister(i);
212 int sp_offset = fpu_reg_save_offsets[i];
213 __ stf(FloatRegisterImpl::S, r, SP, (sp_offset * BytesPerWord) + STACK_BIAS);
214 }
215 }
216 }
217
218 void C1_MacroAssembler::restore_live_registers(bool restore_fpu_registers) {
219 for (int i = 0; i < FrameMap::nof_cpu_regs; i++) {
220 Register r = as_Register(i);
221 if (r == G1 || r == G3 || r == G4 || r == G5) {
222 __ ld_ptr(SP, (cpu_reg_save_offsets[i] * BytesPerWord) + STACK_BIAS, r);
223 }
224 }
225
226 if (restore_fpu_registers) {
227 for (int i = 0; i < FrameMap::nof_fpu_regs; i++) {
228 FloatRegister r = as_FloatRegister(i);
229 __ ldf(FloatRegisterImpl::S, SP, (fpu_reg_save_offsets[i] * BytesPerWord) + STACK_BIAS, r);
230 }
231 }
232 }
233
234 #undef __
235 #define __ sasm->
236
237 static OopMap* save_live_registers(StubAssembler* sasm, bool save_fpu_registers = true) {
238 sasm->save_live_registers_no_oop_map(save_fpu_registers);
239 return generate_oop_map(sasm, save_fpu_registers);
240 }
241
242 static void restore_live_registers(StubAssembler* sasm, bool restore_fpu_registers = true) {
243 sasm->restore_live_registers(restore_fpu_registers);
244 }
245
246
247 void Runtime1::initialize_pd() {
248 // compute word offsets from SP at which live (non-windowed) registers are captured by stub routines
249 //
250 // A stub routine will have a frame that is at least large enough to hold
251 // a register window save area (obviously) and the volatile g registers
252 // and floating registers. A user of save_live_registers can have a frame
253 // that has more scratch area in it (although typically they will use L-regs).
254 // in that case the frame will look like this (stack growing down)
255 //
256 // FP -> | |
257 // | scratch mem |
258 // | " " |
259 // --------------
260 // | float regs |
261 // | " " |
262 // ---------------
263 // | G regs |
264 // | " " |
|
740 break;
741
742 case dtrace_object_alloc_id:
743 { // O0: object
744 __ set_info("dtrace_object_alloc", dont_gc_arguments);
745 // we can't gc here so skip the oopmap but make sure that all
746 // the live registers get saved.
747 save_live_registers(sasm);
748
749 __ save_thread(L7_thread_cache);
750 __ call(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc),
751 relocInfo::runtime_call_type);
752 __ delayed()->mov(I0, O0);
753 __ restore_thread(L7_thread_cache);
754
755 restore_live_registers(sasm);
756 __ ret();
757 __ delayed()->restore();
758 }
759 break;
760
761 #if INCLUDE_ALL_GCS
762 case g1_pre_barrier_slow_id:
763 { // G4: previous value of memory
764 BarrierSet* bs = BarrierSet::barrier_set();
765 if (bs->kind() != BarrierSet::G1BarrierSet) {
766 __ save_frame(0);
767 __ set((int)id, O1);
768 __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), I0);
769 __ should_not_reach_here();
770 break;
771 }
772
773 __ set_info("g1_pre_barrier_slow_id", dont_gc_arguments);
774
775 Register pre_val = G4;
776 Register tmp = G1_scratch;
777 Register tmp2 = G3_scratch;
778
779 Label refill, restart;
780 int satb_q_active_byte_offset = in_bytes(G1ThreadLocalData::satb_mark_queue_active_offset());
781 int satb_q_index_byte_offset = in_bytes(G1ThreadLocalData::satb_mark_queue_index_offset());
782 int satb_q_buf_byte_offset = in_bytes(G1ThreadLocalData::satb_mark_queue_buffer_offset());
783
784 // Is marking still active?
785 if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
786 __ ld(G2_thread, satb_q_active_byte_offset, tmp);
787 } else {
788 assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
789 __ ldsb(G2_thread, satb_q_active_byte_offset, tmp);
790 }
791 __ cmp_and_br_short(tmp, G0, Assembler::notEqual, Assembler::pt, restart);
792 __ retl();
793 __ delayed()->nop();
794
795 __ bind(restart);
796 // Load the index into the SATB buffer. SATBMarkQueue::_index is a
797 // size_t so ld_ptr is appropriate
798 __ ld_ptr(G2_thread, satb_q_index_byte_offset, tmp);
799
800 // index == 0?
801 __ cmp_and_brx_short(tmp, G0, Assembler::equal, Assembler::pn, refill);
802
803 __ ld_ptr(G2_thread, satb_q_buf_byte_offset, tmp2);
804 __ sub(tmp, oopSize, tmp);
805
806 __ st_ptr(pre_val, tmp2, tmp); // [_buf + index] := <address_of_card>
807 // Use return-from-leaf
808 __ retl();
809 __ delayed()->st_ptr(tmp, G2_thread, satb_q_index_byte_offset);
810
811 __ bind(refill);
812
813 save_live_registers(sasm);
814
815 __ call_VM_leaf(L7_thread_cache,
816 CAST_FROM_FN_PTR(address,
817 SATBMarkQueueSet::handle_zero_index_for_thread),
818 G2_thread);
819
820 restore_live_registers(sasm);
821
822 __ br(Assembler::always, /*annul*/false, Assembler::pt, restart);
823 __ delayed()->restore();
824 }
825 break;
826
827 case g1_post_barrier_slow_id:
828 {
829 BarrierSet* bs = BarrierSet::barrier_set();
830 if (bs->kind() != BarrierSet::G1BarrierSet) {
831 __ save_frame(0);
832 __ set((int)id, O1);
833 __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), I0);
834 __ should_not_reach_here();
835 break;
836 }
837
838 __ set_info("g1_post_barrier_slow_id", dont_gc_arguments);
839
840 Register addr = G4;
841 Register cardtable = G5;
842 Register tmp = G1_scratch;
843 Register tmp2 = G3_scratch;
844 jbyte* byte_map_base = ci_card_table_address();
845
846 Label not_already_dirty, restart, refill, young_card;
847
848 __ srlx(addr, CardTable::card_shift, addr);
849
850 AddressLiteral rs(byte_map_base);
851 __ set(rs, cardtable); // cardtable := <card table base>
852 __ ldub(addr, cardtable, tmp); // tmp := [addr + cardtable]
853
854 __ cmp_and_br_short(tmp, G1CardTable::g1_young_card_val(), Assembler::equal, Assembler::pt, young_card);
855
856 __ membar(Assembler::Membar_mask_bits(Assembler::StoreLoad));
857 __ ldub(addr, cardtable, tmp); // tmp := [addr + cardtable]
858
859 assert(CardTable::dirty_card_val() == 0, "otherwise check this code");
860 __ cmp_and_br_short(tmp, G0, Assembler::notEqual, Assembler::pt, not_already_dirty);
861
862 __ bind(young_card);
863 // We didn't take the branch, so we're already dirty: return.
864 // Use return-from-leaf
865 __ retl();
866 __ delayed()->nop();
867
868 // Not dirty.
869 __ bind(not_already_dirty);
870
871 // Get cardtable + tmp into a reg by itself
872 __ add(addr, cardtable, tmp2);
873
874 // First, dirty it.
875 __ stb(G0, tmp2, 0); // [cardPtr] := 0 (i.e., dirty).
876
877 Register tmp3 = cardtable;
878 Register tmp4 = tmp;
879
880 // these registers are now dead
881 addr = cardtable = tmp = noreg;
882
883 int dirty_card_q_index_byte_offset = in_bytes(G1ThreadLocalData::dirty_card_queue_index_offset());
884 int dirty_card_q_buf_byte_offset = in_bytes(G1ThreadLocalData::dirty_card_queue_buffer_offset());
885
886 __ bind(restart);
887
888 // Get the index into the update buffer. DirtyCardQueue::_index is
889 // a size_t so ld_ptr is appropriate here.
890 __ ld_ptr(G2_thread, dirty_card_q_index_byte_offset, tmp3);
891
892 // index == 0?
893 __ cmp_and_brx_short(tmp3, G0, Assembler::equal, Assembler::pn, refill);
894
895 __ ld_ptr(G2_thread, dirty_card_q_buf_byte_offset, tmp4);
896 __ sub(tmp3, oopSize, tmp3);
897
898 __ st_ptr(tmp2, tmp4, tmp3); // [_buf + index] := <address_of_card>
899 // Use return-from-leaf
900 __ retl();
901 __ delayed()->st_ptr(tmp3, G2_thread, dirty_card_q_index_byte_offset);
902
903 __ bind(refill);
904
905 save_live_registers(sasm);
906
907 __ call_VM_leaf(L7_thread_cache,
908 CAST_FROM_FN_PTR(address,
909 DirtyCardQueueSet::handle_zero_index_for_thread),
910 G2_thread);
911
912 restore_live_registers(sasm);
913
914 __ br(Assembler::always, /*annul*/false, Assembler::pt, restart);
915 __ delayed()->restore();
916 }
917 break;
918 #endif // INCLUDE_ALL_GCS
919
920 case predicate_failed_trap_id:
921 {
922 __ set_info("predicate_failed_trap", dont_gc_arguments);
923 OopMap* oop_map = save_live_registers(sasm);
924
925 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, predicate_failed_trap));
926
927 oop_maps = new OopMapSet();
928 oop_maps->add_gc_map(call_offset, oop_map);
929
930 DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
931 assert(deopt_blob != NULL, "deoptimization blob must have been created");
932 restore_live_registers(sasm);
933
934 AddressLiteral dest(deopt_blob->unpack_with_reexecution());
935 __ jump_to(dest, O0);
936 __ delayed()->restore();
937 }
|
753 break;
754
755 case dtrace_object_alloc_id:
756 { // O0: object
757 __ set_info("dtrace_object_alloc", dont_gc_arguments);
758 // we can't gc here so skip the oopmap but make sure that all
759 // the live registers get saved.
760 save_live_registers(sasm);
761
762 __ save_thread(L7_thread_cache);
763 __ call(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc),
764 relocInfo::runtime_call_type);
765 __ delayed()->mov(I0, O0);
766 __ restore_thread(L7_thread_cache);
767
768 restore_live_registers(sasm);
769 __ ret();
770 __ delayed()->restore();
771 }
772 break;
773
774 case predicate_failed_trap_id:
775 {
776 __ set_info("predicate_failed_trap", dont_gc_arguments);
777 OopMap* oop_map = save_live_registers(sasm);
778
779 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, predicate_failed_trap));
780
781 oop_maps = new OopMapSet();
782 oop_maps->add_gc_map(call_offset, oop_map);
783
784 DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
785 assert(deopt_blob != NULL, "deoptimization blob must have been created");
786 restore_live_registers(sasm);
787
788 AddressLiteral dest(deopt_blob->unpack_with_reexecution());
789 __ jump_to(dest, O0);
790 __ delayed()->restore();
791 }
|