Mercurial > hg > graal-jvmci-8
comparison src/cpu/x86/vm/sharedRuntime_x86_64.cpp @ 6792:137868b7aa6f
7196199: java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
Summary: Save whole XMM/YMM registers in safepoint interrupt handler.
Reviewed-by: roland, twisti
author | kvn |
---|---|
date | Mon, 17 Sep 2012 19:39:07 -0700 |
parents | 2cb2f30450c7 |
children | 18fb7da42534 |
comparison
equal
deleted
inserted
replaced
6791:8d3cc6612bd1 | 6792:137868b7aa6f |
---|---|
114 return_off, returnH_off, // slot for return address | 114 return_off, returnH_off, // slot for return address |
115 reg_save_size // size in compiler stack slots | 115 reg_save_size // size in compiler stack slots |
116 }; | 116 }; |
117 | 117 |
118 public: | 118 public: |
119 static OopMap* save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words); | 119 static OopMap* save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors = false); |
120 static void restore_live_registers(MacroAssembler* masm); | 120 static void restore_live_registers(MacroAssembler* masm, bool restore_vectors = false); |
121 | 121 |
122 // Offsets into the register save area | 122 // Offsets into the register save area |
123 // Used by deoptimization when it is managing result register | 123 // Used by deoptimization when it is managing result register |
124 // values on its own | 124 // values on its own |
125 | 125 |
132 // During deoptimization only the result registers need to be restored, | 132 // During deoptimization only the result registers need to be restored, |
133 // all the other values have already been extracted. | 133 // all the other values have already been extracted. |
134 static void restore_result_registers(MacroAssembler* masm); | 134 static void restore_result_registers(MacroAssembler* masm); |
135 }; | 135 }; |
136 | 136 |
137 OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words) { | 137 OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors) { |
138 int vect_words = 0; | |
139 #ifdef COMPILER2 | |
140 if (save_vectors) { | |
141 assert(UseAVX > 0, "256bit vectors are supported only with AVX"); | |
142 assert(MaxVectorSize == 32, "only 256bit vectors are supported now"); | |
143 // Save upper half of YMM registes | |
144 vect_words = 16 * 16 / wordSize; | |
145 additional_frame_words += vect_words; | |
146 } | |
147 #else | |
148 assert(!save_vectors, "vectors are generated only by C2"); | |
149 #endif | |
138 | 150 |
139 // Always make the frame size 16-byte aligned | 151 // Always make the frame size 16-byte aligned |
140 int frame_size_in_bytes = round_to(additional_frame_words*wordSize + | 152 int frame_size_in_bytes = round_to(additional_frame_words*wordSize + |
141 reg_save_size*BytesPerInt, 16); | 153 reg_save_size*BytesPerInt, 16); |
142 // OopMap frame size is in compiler stack slots (jint's) not bytes or words | 154 // OopMap frame size is in compiler stack slots (jint's) not bytes or words |
153 // We push rpb twice in this sequence because we want the real rbp | 165 // We push rpb twice in this sequence because we want the real rbp |
154 // to be under the return like a normal enter. | 166 // to be under the return like a normal enter. |
155 | 167 |
156 __ enter(); // rsp becomes 16-byte aligned here | 168 __ enter(); // rsp becomes 16-byte aligned here |
157 __ push_CPU_state(); // Push a multiple of 16 bytes | 169 __ push_CPU_state(); // Push a multiple of 16 bytes |
170 | |
171 if (vect_words > 0) { | |
172 assert(vect_words*wordSize == 256, ""); | |
173 __ subptr(rsp, 256); // Save upper half of YMM registes | |
174 __ vextractf128h(Address(rsp, 0),xmm0); | |
175 __ vextractf128h(Address(rsp, 16),xmm1); | |
176 __ vextractf128h(Address(rsp, 32),xmm2); | |
177 __ vextractf128h(Address(rsp, 48),xmm3); | |
178 __ vextractf128h(Address(rsp, 64),xmm4); | |
179 __ vextractf128h(Address(rsp, 80),xmm5); | |
180 __ vextractf128h(Address(rsp, 96),xmm6); | |
181 __ vextractf128h(Address(rsp,112),xmm7); | |
182 __ vextractf128h(Address(rsp,128),xmm8); | |
183 __ vextractf128h(Address(rsp,144),xmm9); | |
184 __ vextractf128h(Address(rsp,160),xmm10); | |
185 __ vextractf128h(Address(rsp,176),xmm11); | |
186 __ vextractf128h(Address(rsp,192),xmm12); | |
187 __ vextractf128h(Address(rsp,208),xmm13); | |
188 __ vextractf128h(Address(rsp,224),xmm14); | |
189 __ vextractf128h(Address(rsp,240),xmm15); | |
190 } | |
158 if (frame::arg_reg_save_area_bytes != 0) { | 191 if (frame::arg_reg_save_area_bytes != 0) { |
159 // Allocate argument register save area | 192 // Allocate argument register save area |
160 __ subptr(rsp, frame::arg_reg_save_area_bytes); | 193 __ subptr(rsp, frame::arg_reg_save_area_bytes); |
161 } | 194 } |
162 | 195 |
165 // will allow deoptimization at this safepoint to find all possible | 198 // will allow deoptimization at this safepoint to find all possible |
166 // debug-info recordings, as well as let GC find all oops. | 199 // debug-info recordings, as well as let GC find all oops. |
167 | 200 |
168 OopMapSet *oop_maps = new OopMapSet(); | 201 OopMapSet *oop_maps = new OopMapSet(); |
169 OopMap* map = new OopMap(frame_size_in_slots, 0); | 202 OopMap* map = new OopMap(frame_size_in_slots, 0); |
170 map->set_callee_saved(VMRegImpl::stack2reg( rax_off + additional_frame_slots), rax->as_VMReg()); | 203 |
171 map->set_callee_saved(VMRegImpl::stack2reg( rcx_off + additional_frame_slots), rcx->as_VMReg()); | 204 #define STACK_OFFSET(x) VMRegImpl::stack2reg((x) + additional_frame_slots) |
172 map->set_callee_saved(VMRegImpl::stack2reg( rdx_off + additional_frame_slots), rdx->as_VMReg()); | 205 |
173 map->set_callee_saved(VMRegImpl::stack2reg( rbx_off + additional_frame_slots), rbx->as_VMReg()); | 206 map->set_callee_saved(STACK_OFFSET( rax_off ), rax->as_VMReg()); |
207 map->set_callee_saved(STACK_OFFSET( rcx_off ), rcx->as_VMReg()); | |
208 map->set_callee_saved(STACK_OFFSET( rdx_off ), rdx->as_VMReg()); | |
209 map->set_callee_saved(STACK_OFFSET( rbx_off ), rbx->as_VMReg()); | |
174 // rbp location is known implicitly by the frame sender code, needs no oopmap | 210 // rbp location is known implicitly by the frame sender code, needs no oopmap |
175 // and the location where rbp was saved by is ignored | 211 // and the location where rbp was saved by is ignored |
176 map->set_callee_saved(VMRegImpl::stack2reg( rsi_off + additional_frame_slots), rsi->as_VMReg()); | 212 map->set_callee_saved(STACK_OFFSET( rsi_off ), rsi->as_VMReg()); |
177 map->set_callee_saved(VMRegImpl::stack2reg( rdi_off + additional_frame_slots), rdi->as_VMReg()); | 213 map->set_callee_saved(STACK_OFFSET( rdi_off ), rdi->as_VMReg()); |
178 map->set_callee_saved(VMRegImpl::stack2reg( r8_off + additional_frame_slots), r8->as_VMReg()); | 214 map->set_callee_saved(STACK_OFFSET( r8_off ), r8->as_VMReg()); |
179 map->set_callee_saved(VMRegImpl::stack2reg( r9_off + additional_frame_slots), r9->as_VMReg()); | 215 map->set_callee_saved(STACK_OFFSET( r9_off ), r9->as_VMReg()); |
180 map->set_callee_saved(VMRegImpl::stack2reg( r10_off + additional_frame_slots), r10->as_VMReg()); | 216 map->set_callee_saved(STACK_OFFSET( r10_off ), r10->as_VMReg()); |
181 map->set_callee_saved(VMRegImpl::stack2reg( r11_off + additional_frame_slots), r11->as_VMReg()); | 217 map->set_callee_saved(STACK_OFFSET( r11_off ), r11->as_VMReg()); |
182 map->set_callee_saved(VMRegImpl::stack2reg( r12_off + additional_frame_slots), r12->as_VMReg()); | 218 map->set_callee_saved(STACK_OFFSET( r12_off ), r12->as_VMReg()); |
183 map->set_callee_saved(VMRegImpl::stack2reg( r13_off + additional_frame_slots), r13->as_VMReg()); | 219 map->set_callee_saved(STACK_OFFSET( r13_off ), r13->as_VMReg()); |
184 map->set_callee_saved(VMRegImpl::stack2reg( r14_off + additional_frame_slots), r14->as_VMReg()); | 220 map->set_callee_saved(STACK_OFFSET( r14_off ), r14->as_VMReg()); |
185 map->set_callee_saved(VMRegImpl::stack2reg( r15_off + additional_frame_slots), r15->as_VMReg()); | 221 map->set_callee_saved(STACK_OFFSET( r15_off ), r15->as_VMReg()); |
186 map->set_callee_saved(VMRegImpl::stack2reg(xmm0_off + additional_frame_slots), xmm0->as_VMReg()); | 222 map->set_callee_saved(STACK_OFFSET(xmm0_off ), xmm0->as_VMReg()); |
187 map->set_callee_saved(VMRegImpl::stack2reg(xmm1_off + additional_frame_slots), xmm1->as_VMReg()); | 223 map->set_callee_saved(STACK_OFFSET(xmm1_off ), xmm1->as_VMReg()); |
188 map->set_callee_saved(VMRegImpl::stack2reg(xmm2_off + additional_frame_slots), xmm2->as_VMReg()); | 224 map->set_callee_saved(STACK_OFFSET(xmm2_off ), xmm2->as_VMReg()); |
189 map->set_callee_saved(VMRegImpl::stack2reg(xmm3_off + additional_frame_slots), xmm3->as_VMReg()); | 225 map->set_callee_saved(STACK_OFFSET(xmm3_off ), xmm3->as_VMReg()); |
190 map->set_callee_saved(VMRegImpl::stack2reg(xmm4_off + additional_frame_slots), xmm4->as_VMReg()); | 226 map->set_callee_saved(STACK_OFFSET(xmm4_off ), xmm4->as_VMReg()); |
191 map->set_callee_saved(VMRegImpl::stack2reg(xmm5_off + additional_frame_slots), xmm5->as_VMReg()); | 227 map->set_callee_saved(STACK_OFFSET(xmm5_off ), xmm5->as_VMReg()); |
192 map->set_callee_saved(VMRegImpl::stack2reg(xmm6_off + additional_frame_slots), xmm6->as_VMReg()); | 228 map->set_callee_saved(STACK_OFFSET(xmm6_off ), xmm6->as_VMReg()); |
193 map->set_callee_saved(VMRegImpl::stack2reg(xmm7_off + additional_frame_slots), xmm7->as_VMReg()); | 229 map->set_callee_saved(STACK_OFFSET(xmm7_off ), xmm7->as_VMReg()); |
194 map->set_callee_saved(VMRegImpl::stack2reg(xmm8_off + additional_frame_slots), xmm8->as_VMReg()); | 230 map->set_callee_saved(STACK_OFFSET(xmm8_off ), xmm8->as_VMReg()); |
195 map->set_callee_saved(VMRegImpl::stack2reg(xmm9_off + additional_frame_slots), xmm9->as_VMReg()); | 231 map->set_callee_saved(STACK_OFFSET(xmm9_off ), xmm9->as_VMReg()); |
196 map->set_callee_saved(VMRegImpl::stack2reg(xmm10_off + additional_frame_slots), xmm10->as_VMReg()); | 232 map->set_callee_saved(STACK_OFFSET(xmm10_off), xmm10->as_VMReg()); |
197 map->set_callee_saved(VMRegImpl::stack2reg(xmm11_off + additional_frame_slots), xmm11->as_VMReg()); | 233 map->set_callee_saved(STACK_OFFSET(xmm11_off), xmm11->as_VMReg()); |
198 map->set_callee_saved(VMRegImpl::stack2reg(xmm12_off + additional_frame_slots), xmm12->as_VMReg()); | 234 map->set_callee_saved(STACK_OFFSET(xmm12_off), xmm12->as_VMReg()); |
199 map->set_callee_saved(VMRegImpl::stack2reg(xmm13_off + additional_frame_slots), xmm13->as_VMReg()); | 235 map->set_callee_saved(STACK_OFFSET(xmm13_off), xmm13->as_VMReg()); |
200 map->set_callee_saved(VMRegImpl::stack2reg(xmm14_off + additional_frame_slots), xmm14->as_VMReg()); | 236 map->set_callee_saved(STACK_OFFSET(xmm14_off), xmm14->as_VMReg()); |
201 map->set_callee_saved(VMRegImpl::stack2reg(xmm15_off + additional_frame_slots), xmm15->as_VMReg()); | 237 map->set_callee_saved(STACK_OFFSET(xmm15_off), xmm15->as_VMReg()); |
202 | 238 |
203 // %%% These should all be a waste but we'll keep things as they were for now | 239 // %%% These should all be a waste but we'll keep things as they were for now |
204 if (true) { | 240 if (true) { |
205 map->set_callee_saved(VMRegImpl::stack2reg( raxH_off + additional_frame_slots), | 241 map->set_callee_saved(STACK_OFFSET( raxH_off ), rax->as_VMReg()->next()); |
206 rax->as_VMReg()->next()); | 242 map->set_callee_saved(STACK_OFFSET( rcxH_off ), rcx->as_VMReg()->next()); |
207 map->set_callee_saved(VMRegImpl::stack2reg( rcxH_off + additional_frame_slots), | 243 map->set_callee_saved(STACK_OFFSET( rdxH_off ), rdx->as_VMReg()->next()); |
208 rcx->as_VMReg()->next()); | 244 map->set_callee_saved(STACK_OFFSET( rbxH_off ), rbx->as_VMReg()->next()); |
209 map->set_callee_saved(VMRegImpl::stack2reg( rdxH_off + additional_frame_slots), | |
210 rdx->as_VMReg()->next()); | |
211 map->set_callee_saved(VMRegImpl::stack2reg( rbxH_off + additional_frame_slots), | |
212 rbx->as_VMReg()->next()); | |
213 // rbp location is known implicitly by the frame sender code, needs no oopmap | 245 // rbp location is known implicitly by the frame sender code, needs no oopmap |
214 map->set_callee_saved(VMRegImpl::stack2reg( rsiH_off + additional_frame_slots), | 246 map->set_callee_saved(STACK_OFFSET( rsiH_off ), rsi->as_VMReg()->next()); |
215 rsi->as_VMReg()->next()); | 247 map->set_callee_saved(STACK_OFFSET( rdiH_off ), rdi->as_VMReg()->next()); |
216 map->set_callee_saved(VMRegImpl::stack2reg( rdiH_off + additional_frame_slots), | 248 map->set_callee_saved(STACK_OFFSET( r8H_off ), r8->as_VMReg()->next()); |
217 rdi->as_VMReg()->next()); | 249 map->set_callee_saved(STACK_OFFSET( r9H_off ), r9->as_VMReg()->next()); |
218 map->set_callee_saved(VMRegImpl::stack2reg( r8H_off + additional_frame_slots), | 250 map->set_callee_saved(STACK_OFFSET( r10H_off ), r10->as_VMReg()->next()); |
219 r8->as_VMReg()->next()); | 251 map->set_callee_saved(STACK_OFFSET( r11H_off ), r11->as_VMReg()->next()); |
220 map->set_callee_saved(VMRegImpl::stack2reg( r9H_off + additional_frame_slots), | 252 map->set_callee_saved(STACK_OFFSET( r12H_off ), r12->as_VMReg()->next()); |
221 r9->as_VMReg()->next()); | 253 map->set_callee_saved(STACK_OFFSET( r13H_off ), r13->as_VMReg()->next()); |
222 map->set_callee_saved(VMRegImpl::stack2reg( r10H_off + additional_frame_slots), | 254 map->set_callee_saved(STACK_OFFSET( r14H_off ), r14->as_VMReg()->next()); |
223 r10->as_VMReg()->next()); | 255 map->set_callee_saved(STACK_OFFSET( r15H_off ), r15->as_VMReg()->next()); |
224 map->set_callee_saved(VMRegImpl::stack2reg( r11H_off + additional_frame_slots), | 256 map->set_callee_saved(STACK_OFFSET(xmm0H_off ), xmm0->as_VMReg()->next()); |
225 r11->as_VMReg()->next()); | 257 map->set_callee_saved(STACK_OFFSET(xmm1H_off ), xmm1->as_VMReg()->next()); |
226 map->set_callee_saved(VMRegImpl::stack2reg( r12H_off + additional_frame_slots), | 258 map->set_callee_saved(STACK_OFFSET(xmm2H_off ), xmm2->as_VMReg()->next()); |
227 r12->as_VMReg()->next()); | 259 map->set_callee_saved(STACK_OFFSET(xmm3H_off ), xmm3->as_VMReg()->next()); |
228 map->set_callee_saved(VMRegImpl::stack2reg( r13H_off + additional_frame_slots), | 260 map->set_callee_saved(STACK_OFFSET(xmm4H_off ), xmm4->as_VMReg()->next()); |
229 r13->as_VMReg()->next()); | 261 map->set_callee_saved(STACK_OFFSET(xmm5H_off ), xmm5->as_VMReg()->next()); |
230 map->set_callee_saved(VMRegImpl::stack2reg( r14H_off + additional_frame_slots), | 262 map->set_callee_saved(STACK_OFFSET(xmm6H_off ), xmm6->as_VMReg()->next()); |
231 r14->as_VMReg()->next()); | 263 map->set_callee_saved(STACK_OFFSET(xmm7H_off ), xmm7->as_VMReg()->next()); |
232 map->set_callee_saved(VMRegImpl::stack2reg( r15H_off + additional_frame_slots), | 264 map->set_callee_saved(STACK_OFFSET(xmm8H_off ), xmm8->as_VMReg()->next()); |
233 r15->as_VMReg()->next()); | 265 map->set_callee_saved(STACK_OFFSET(xmm9H_off ), xmm9->as_VMReg()->next()); |
234 map->set_callee_saved(VMRegImpl::stack2reg(xmm0H_off + additional_frame_slots), | 266 map->set_callee_saved(STACK_OFFSET(xmm10H_off), xmm10->as_VMReg()->next()); |
235 xmm0->as_VMReg()->next()); | 267 map->set_callee_saved(STACK_OFFSET(xmm11H_off), xmm11->as_VMReg()->next()); |
236 map->set_callee_saved(VMRegImpl::stack2reg(xmm1H_off + additional_frame_slots), | 268 map->set_callee_saved(STACK_OFFSET(xmm12H_off), xmm12->as_VMReg()->next()); |
237 xmm1->as_VMReg()->next()); | 269 map->set_callee_saved(STACK_OFFSET(xmm13H_off), xmm13->as_VMReg()->next()); |
238 map->set_callee_saved(VMRegImpl::stack2reg(xmm2H_off + additional_frame_slots), | 270 map->set_callee_saved(STACK_OFFSET(xmm14H_off), xmm14->as_VMReg()->next()); |
239 xmm2->as_VMReg()->next()); | 271 map->set_callee_saved(STACK_OFFSET(xmm15H_off), xmm15->as_VMReg()->next()); |
240 map->set_callee_saved(VMRegImpl::stack2reg(xmm3H_off + additional_frame_slots), | |
241 xmm3->as_VMReg()->next()); | |
242 map->set_callee_saved(VMRegImpl::stack2reg(xmm4H_off + additional_frame_slots), | |
243 xmm4->as_VMReg()->next()); | |
244 map->set_callee_saved(VMRegImpl::stack2reg(xmm5H_off + additional_frame_slots), | |
245 xmm5->as_VMReg()->next()); | |
246 map->set_callee_saved(VMRegImpl::stack2reg(xmm6H_off + additional_frame_slots), | |
247 xmm6->as_VMReg()->next()); | |
248 map->set_callee_saved(VMRegImpl::stack2reg(xmm7H_off + additional_frame_slots), | |
249 xmm7->as_VMReg()->next()); | |
250 map->set_callee_saved(VMRegImpl::stack2reg(xmm8H_off + additional_frame_slots), | |
251 xmm8->as_VMReg()->next()); | |
252 map->set_callee_saved(VMRegImpl::stack2reg(xmm9H_off + additional_frame_slots), | |
253 xmm9->as_VMReg()->next()); | |
254 map->set_callee_saved(VMRegImpl::stack2reg(xmm10H_off + additional_frame_slots), | |
255 xmm10->as_VMReg()->next()); | |
256 map->set_callee_saved(VMRegImpl::stack2reg(xmm11H_off + additional_frame_slots), | |
257 xmm11->as_VMReg()->next()); | |
258 map->set_callee_saved(VMRegImpl::stack2reg(xmm12H_off + additional_frame_slots), | |
259 xmm12->as_VMReg()->next()); | |
260 map->set_callee_saved(VMRegImpl::stack2reg(xmm13H_off + additional_frame_slots), | |
261 xmm13->as_VMReg()->next()); | |
262 map->set_callee_saved(VMRegImpl::stack2reg(xmm14H_off + additional_frame_slots), | |
263 xmm14->as_VMReg()->next()); | |
264 map->set_callee_saved(VMRegImpl::stack2reg(xmm15H_off + additional_frame_slots), | |
265 xmm15->as_VMReg()->next()); | |
266 } | 272 } |
267 | 273 |
268 return map; | 274 return map; |
269 } | 275 } |
270 | 276 |
271 void RegisterSaver::restore_live_registers(MacroAssembler* masm) { | 277 void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_vectors) { |
272 if (frame::arg_reg_save_area_bytes != 0) { | 278 if (frame::arg_reg_save_area_bytes != 0) { |
273 // Pop arg register save area | 279 // Pop arg register save area |
274 __ addptr(rsp, frame::arg_reg_save_area_bytes); | 280 __ addptr(rsp, frame::arg_reg_save_area_bytes); |
275 } | 281 } |
282 #ifdef COMPILER2 | |
283 if (restore_vectors) { | |
284 // Restore upper half of YMM registes. | |
285 assert(UseAVX > 0, "256bit vectors are supported only with AVX"); | |
286 assert(MaxVectorSize == 32, "only 256bit vectors are supported now"); | |
287 __ vinsertf128h(xmm0, Address(rsp, 0)); | |
288 __ vinsertf128h(xmm1, Address(rsp, 16)); | |
289 __ vinsertf128h(xmm2, Address(rsp, 32)); | |
290 __ vinsertf128h(xmm3, Address(rsp, 48)); | |
291 __ vinsertf128h(xmm4, Address(rsp, 64)); | |
292 __ vinsertf128h(xmm5, Address(rsp, 80)); | |
293 __ vinsertf128h(xmm6, Address(rsp, 96)); | |
294 __ vinsertf128h(xmm7, Address(rsp,112)); | |
295 __ vinsertf128h(xmm8, Address(rsp,128)); | |
296 __ vinsertf128h(xmm9, Address(rsp,144)); | |
297 __ vinsertf128h(xmm10, Address(rsp,160)); | |
298 __ vinsertf128h(xmm11, Address(rsp,176)); | |
299 __ vinsertf128h(xmm12, Address(rsp,192)); | |
300 __ vinsertf128h(xmm13, Address(rsp,208)); | |
301 __ vinsertf128h(xmm14, Address(rsp,224)); | |
302 __ vinsertf128h(xmm15, Address(rsp,240)); | |
303 __ addptr(rsp, 256); | |
304 } | |
305 #else | |
306 assert(!restore_vectors, "vectors are generated only by C2"); | |
307 #endif | |
276 // Recover CPU state | 308 // Recover CPU state |
277 __ pop_CPU_state(); | 309 __ pop_CPU_state(); |
278 // Get the rbp described implicitly by the calling convention (no oopMap) | 310 // Get the rbp described implicitly by the calling convention (no oopMap) |
279 __ pop(rbp); | 311 __ pop(rbp); |
280 } | 312 } |
293 __ movptr(rax, Address(rsp, rax_offset_in_bytes())); | 325 __ movptr(rax, Address(rsp, rax_offset_in_bytes())); |
294 __ movptr(rdx, Address(rsp, rdx_offset_in_bytes())); | 326 __ movptr(rdx, Address(rsp, rdx_offset_in_bytes())); |
295 | 327 |
296 // Pop all of the register save are off the stack except the return address | 328 // Pop all of the register save are off the stack except the return address |
297 __ addptr(rsp, return_offset_in_bytes()); | 329 __ addptr(rsp, return_offset_in_bytes()); |
330 } | |
331 | |
332 // Is vector's size (in bytes) bigger than a size saved by default? | |
333 // 16 bytes XMM registers are saved by default using fxsave/fxrstor instructions. | |
334 bool SharedRuntime::is_wide_vector(int size) { | |
335 return size > 16; | |
298 } | 336 } |
299 | 337 |
300 // The java_calling_convention describes stack locations as ideal slots on | 338 // The java_calling_convention describes stack locations as ideal slots on |
301 // a frame with no abi restrictions. Since we must observe abi restrictions | 339 // a frame with no abi restrictions. Since we must observe abi restrictions |
302 // (like the placement of the register window) the slots must be biased by | 340 // (like the placement of the register window) the slots must be biased by |
3233 | 3271 |
3234 uint SharedRuntime::out_preserve_stack_slots() { | 3272 uint SharedRuntime::out_preserve_stack_slots() { |
3235 return 0; | 3273 return 0; |
3236 } | 3274 } |
3237 | 3275 |
3238 | |
3239 //------------------------------generate_deopt_blob---------------------------- | 3276 //------------------------------generate_deopt_blob---------------------------- |
3240 void SharedRuntime::generate_deopt_blob() { | 3277 void SharedRuntime::generate_deopt_blob() { |
3241 // Allocate space for the code | 3278 // Allocate space for the code |
3242 ResourceMark rm; | 3279 ResourceMark rm; |
3243 // Setup code generation tools | 3280 // Setup code generation tools |
3738 //------------------------------generate_handler_blob------ | 3775 //------------------------------generate_handler_blob------ |
3739 // | 3776 // |
3740 // Generate a special Compile2Runtime blob that saves all registers, | 3777 // Generate a special Compile2Runtime blob that saves all registers, |
3741 // and setup oopmap. | 3778 // and setup oopmap. |
3742 // | 3779 // |
3743 SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, bool cause_return) { | 3780 SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_type) { |
3744 assert(StubRoutines::forward_exception_entry() != NULL, | 3781 assert(StubRoutines::forward_exception_entry() != NULL, |
3745 "must be generated before"); | 3782 "must be generated before"); |
3746 | 3783 |
3747 ResourceMark rm; | 3784 ResourceMark rm; |
3748 OopMapSet *oop_maps = new OopMapSet(); | 3785 OopMapSet *oop_maps = new OopMapSet(); |
3753 MacroAssembler* masm = new MacroAssembler(&buffer); | 3790 MacroAssembler* masm = new MacroAssembler(&buffer); |
3754 | 3791 |
3755 address start = __ pc(); | 3792 address start = __ pc(); |
3756 address call_pc = NULL; | 3793 address call_pc = NULL; |
3757 int frame_size_in_words; | 3794 int frame_size_in_words; |
3795 bool cause_return = (poll_type == POLL_AT_RETURN); | |
3796 bool save_vectors = (poll_type == POLL_AT_VECTOR_LOOP); | |
3758 | 3797 |
3759 // Make room for return address (or push it again) | 3798 // Make room for return address (or push it again) |
3760 if (!cause_return) { | 3799 if (!cause_return) { |
3761 __ push(rbx); | 3800 __ push(rbx); |
3762 } | 3801 } |
3763 | 3802 |
3764 // Save registers, fpu state, and flags | 3803 // Save registers, fpu state, and flags |
3765 map = RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words); | 3804 map = RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words, save_vectors); |
3766 | 3805 |
3767 // The following is basically a call_VM. However, we need the precise | 3806 // The following is basically a call_VM. However, we need the precise |
3768 // address of the call in order to generate an oopmap. Hence, we do all the | 3807 // address of the call in order to generate an oopmap. Hence, we do all the |
3769 // work outselves. | 3808 // work outselves. |
3770 | 3809 |
3797 __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); | 3836 __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); |
3798 __ jcc(Assembler::equal, noException); | 3837 __ jcc(Assembler::equal, noException); |
3799 | 3838 |
3800 // Exception pending | 3839 // Exception pending |
3801 | 3840 |
3802 RegisterSaver::restore_live_registers(masm); | 3841 RegisterSaver::restore_live_registers(masm, save_vectors); |
3803 | 3842 |
3804 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry())); | 3843 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry())); |
3805 | 3844 |
3806 // No exception case | 3845 // No exception case |
3807 __ bind(noException); | 3846 __ bind(noException); |
3808 | 3847 |
3809 // Normal exit, restore registers and exit. | 3848 // Normal exit, restore registers and exit. |
3810 RegisterSaver::restore_live_registers(masm); | 3849 RegisterSaver::restore_live_registers(masm, save_vectors); |
3811 | 3850 |
3812 __ ret(0); | 3851 __ ret(0); |
3813 | 3852 |
3814 // Make sure all code is generated | 3853 // Make sure all code is generated |
3815 masm->flush(); | 3854 masm->flush(); |