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();