8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifdef COMPILER2
26 #include "asm/macroAssembler.hpp"
27 #include "asm/macroAssembler.inline.hpp"
28 #include "code/vmreg.hpp"
29 #include "interpreter/interpreter.hpp"
30 #include "opto/runtime.hpp"
31 #include "runtime/sharedRuntime.hpp"
32 #include "runtime/stubRoutines.hpp"
33 #include "runtime/vframeArray.hpp"
34 #include "utilities/globalDefinitions.hpp"
35 #include "vmreg_x86.inline.hpp"
36
37 class SimpleRuntimeFrame {
38
39 public:
40
41 // Most of the runtime stubs have this simple frame layout.
42 // This class exists to make the layout shared in one place.
43 // Offsets are for compiler stack slots, which are jints.
44 enum layout {
45 // The frame sender code expects that rbp will be in the "natural" place and
46 // will override any oopMap setting for it. We must therefore force the layout
47 // so that it agrees with the frame sender code.
250 // rax: exception oop
251 // rdx: exception pc in caller or ???
252 // destination: exception handler of caller
253 //
254 // Note: the exception pc MUST be at a call (precise debug information)
255 // Registers rax, rdx, rcx, rsi, rdi, r8-r11 are not callee saved.
256 //
257
258 ExceptionBlob* OptoRuntime::generate_exception_blob() {
259 assert(!OptoRuntime::is_callee_saved_register(RDX_num), "");
260 assert(!OptoRuntime::is_callee_saved_register(RAX_num), "");
261 assert(!OptoRuntime::is_callee_saved_register(RCX_num), "");
262
263 assert(SimpleRuntimeFrame::framesize % 4 == 0, "sp not 16-byte aligned");
264
265 // Allocate space for the code
266 ResourceMark rm;
267 // Setup code generation tools
268 const char* name = OptoRuntime::stub_name(OptoStubId::exception_id);
269 CodeBuffer buffer(name, 2048, 1024);
270 MacroAssembler* masm = new MacroAssembler(&buffer);
271
272
273 address start = __ pc();
274
275 // Exception pc is 'return address' for stack walker
276 __ push(rdx);
277 __ subptr(rsp, SimpleRuntimeFrame::return_off << LogBytesPerInt); // Prolog
278
279 // Save callee-saved registers. See x86_64.ad.
280
281 // rbp is an implicitly saved callee saved register (i.e., the calling
282 // convention will save/restore it in the prolog/epilog). Other than that
283 // there are no callee save registers now that adapter frames are gone.
284
285 __ movptr(Address(rsp, SimpleRuntimeFrame::rbp_off << LogBytesPerInt), rbp);
286
287 // Store exception in Thread object. We cannot pass any arguments to the
288 // handle_exception call, since we do not want to make any assumption
289 // about the size of the frame where the exception happened in.
290 // c_rarg0 is either rdi (Linux) or rcx (Windows).
291 __ movptr(Address(r15_thread, JavaThread::exception_oop_offset()),rax);
292 __ movptr(Address(r15_thread, JavaThread::exception_pc_offset()), rdx);
298 // registers of the frame being removed.
299 //
300 // address OptoRuntime::handle_exception_C(JavaThread* thread)
301
302 // At a method handle call, the stack may not be properly aligned
303 // when returning with an exception.
304 address the_pc = __ pc();
305 __ set_last_Java_frame(noreg, noreg, the_pc, rscratch1);
306 __ mov(c_rarg0, r15_thread);
307 __ andptr(rsp, -(StackAlignmentInBytes)); // Align stack
308 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, OptoRuntime::handle_exception_C)));
309
310 // Set an oopmap for the call site. This oopmap will only be used if we
311 // are unwinding the stack. Hence, all locations will be dead.
312 // Callee-saved registers will be the same as the frame above (i.e.,
313 // handle_exception_stub), since they were restored when we got the
314 // exception.
315
316 OopMapSet* oop_maps = new OopMapSet();
317
318 oop_maps->add_gc_map(the_pc - start, new OopMap(SimpleRuntimeFrame::framesize, 0));
319
320 __ reset_last_Java_frame(false);
321
322 // Restore callee-saved registers
323
324 // rbp is an implicitly saved callee-saved register (i.e., the calling
325 // convention will save restore it in prolog/epilog) Other than that
326 // there are no callee save registers now that adapter frames are gone.
327
328 __ movptr(rbp, Address(rsp, SimpleRuntimeFrame::rbp_off << LogBytesPerInt));
329
330 __ addptr(rsp, SimpleRuntimeFrame::return_off << LogBytesPerInt); // Epilog
331 __ pop(rdx); // No need for exception pc anymore
332
333 // rax: exception handler
334
335 // We have a handler in rax (could be deopt blob).
336 __ mov(r8, rax);
337
338 // Get the exception oop
339 __ movptr(rax, Address(r15_thread, JavaThread::exception_oop_offset()));
340 // Get the exception pc in case we are deoptimized
341 __ movptr(rdx, Address(r15_thread, JavaThread::exception_pc_offset()));
342 #ifdef ASSERT
343 __ movptr(Address(r15_thread, JavaThread::exception_handler_pc_offset()), NULL_WORD);
344 __ movptr(Address(r15_thread, JavaThread::exception_pc_offset()), NULL_WORD);
345 #endif
346 // Clear the exception oop so GC no longer processes it as a root.
347 __ movptr(Address(r15_thread, JavaThread::exception_oop_offset()), NULL_WORD);
348
349 // rax: exception oop
350 // r8: exception handler
351 // rdx: exception pc
352 // Jump to handler
353
354 __ jmp(r8);
355
356 // Make sure all code is generated
357 masm->flush();
358
359 // Set exception blob
360 return ExceptionBlob::create(&buffer, oop_maps, SimpleRuntimeFrame::framesize >> 1);
361 }
362 #endif // COMPILER2
|
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifdef COMPILER2
26 #include "asm/macroAssembler.hpp"
27 #include "asm/macroAssembler.inline.hpp"
28 #include "code/SCCache.hpp"
29 #include "code/vmreg.hpp"
30 #include "interpreter/interpreter.hpp"
31 #include "opto/runtime.hpp"
32 #include "runtime/sharedRuntime.hpp"
33 #include "runtime/stubRoutines.hpp"
34 #include "runtime/vframeArray.hpp"
35 #include "utilities/globalDefinitions.hpp"
36 #include "vmreg_x86.inline.hpp"
37
38 class SimpleRuntimeFrame {
39
40 public:
41
42 // Most of the runtime stubs have this simple frame layout.
43 // This class exists to make the layout shared in one place.
44 // Offsets are for compiler stack slots, which are jints.
45 enum layout {
46 // The frame sender code expects that rbp will be in the "natural" place and
47 // will override any oopMap setting for it. We must therefore force the layout
48 // so that it agrees with the frame sender code.
251 // rax: exception oop
252 // rdx: exception pc in caller or ???
253 // destination: exception handler of caller
254 //
255 // Note: the exception pc MUST be at a call (precise debug information)
256 // Registers rax, rdx, rcx, rsi, rdi, r8-r11 are not callee saved.
257 //
258
259 ExceptionBlob* OptoRuntime::generate_exception_blob() {
260 assert(!OptoRuntime::is_callee_saved_register(RDX_num), "");
261 assert(!OptoRuntime::is_callee_saved_register(RAX_num), "");
262 assert(!OptoRuntime::is_callee_saved_register(RCX_num), "");
263
264 assert(SimpleRuntimeFrame::framesize % 4 == 0, "sp not 16-byte aligned");
265
266 // Allocate space for the code
267 ResourceMark rm;
268 // Setup code generation tools
269 const char* name = OptoRuntime::stub_name(OptoStubId::exception_id);
270 CodeBuffer buffer(name, 2048, 1024);
271
272 int pc_offset = 0;
273 if (SCCache::load_exception_blob(&buffer, &pc_offset)) {
274 OopMapSet* oop_maps = new OopMapSet();
275 oop_maps->add_gc_map(pc_offset, new OopMap(SimpleRuntimeFrame::framesize, 0));
276
277 // Set exception blob
278 _exception_blob = ExceptionBlob::create(&buffer, oop_maps, SimpleRuntimeFrame::framesize >> 1);
279 return _exception_blob;
280 }
281
282 MacroAssembler* masm = new MacroAssembler(&buffer);
283 address start = __ pc();
284
285 // Exception pc is 'return address' for stack walker
286 __ push(rdx);
287 __ subptr(rsp, SimpleRuntimeFrame::return_off << LogBytesPerInt); // Prolog
288
289 // Save callee-saved registers. See x86_64.ad.
290
291 // rbp is an implicitly saved callee saved register (i.e., the calling
292 // convention will save/restore it in the prolog/epilog). Other than that
293 // there are no callee save registers now that adapter frames are gone.
294
295 __ movptr(Address(rsp, SimpleRuntimeFrame::rbp_off << LogBytesPerInt), rbp);
296
297 // Store exception in Thread object. We cannot pass any arguments to the
298 // handle_exception call, since we do not want to make any assumption
299 // about the size of the frame where the exception happened in.
300 // c_rarg0 is either rdi (Linux) or rcx (Windows).
301 __ movptr(Address(r15_thread, JavaThread::exception_oop_offset()),rax);
302 __ movptr(Address(r15_thread, JavaThread::exception_pc_offset()), rdx);
308 // registers of the frame being removed.
309 //
310 // address OptoRuntime::handle_exception_C(JavaThread* thread)
311
312 // At a method handle call, the stack may not be properly aligned
313 // when returning with an exception.
314 address the_pc = __ pc();
315 __ set_last_Java_frame(noreg, noreg, the_pc, rscratch1);
316 __ mov(c_rarg0, r15_thread);
317 __ andptr(rsp, -(StackAlignmentInBytes)); // Align stack
318 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, OptoRuntime::handle_exception_C)));
319
320 // Set an oopmap for the call site. This oopmap will only be used if we
321 // are unwinding the stack. Hence, all locations will be dead.
322 // Callee-saved registers will be the same as the frame above (i.e.,
323 // handle_exception_stub), since they were restored when we got the
324 // exception.
325
326 OopMapSet* oop_maps = new OopMapSet();
327
328 pc_offset = the_pc - start;
329 oop_maps->add_gc_map(pc_offset, new OopMap(SimpleRuntimeFrame::framesize, 0));
330
331 __ reset_last_Java_frame(false);
332
333 // Restore callee-saved registers
334
335 // rbp is an implicitly saved callee-saved register (i.e., the calling
336 // convention will save restore it in prolog/epilog) Other than that
337 // there are no callee save registers now that adapter frames are gone.
338
339 __ movptr(rbp, Address(rsp, SimpleRuntimeFrame::rbp_off << LogBytesPerInt));
340
341 __ addptr(rsp, SimpleRuntimeFrame::return_off << LogBytesPerInt); // Epilog
342 __ pop(rdx); // No need for exception pc anymore
343
344 // rax: exception handler
345
346 // We have a handler in rax (could be deopt blob).
347 __ mov(r8, rax);
348
349 // Get the exception oop
350 __ movptr(rax, Address(r15_thread, JavaThread::exception_oop_offset()));
351 // Get the exception pc in case we are deoptimized
352 __ movptr(rdx, Address(r15_thread, JavaThread::exception_pc_offset()));
353 #ifdef ASSERT
354 __ movptr(Address(r15_thread, JavaThread::exception_handler_pc_offset()), NULL_WORD);
355 __ movptr(Address(r15_thread, JavaThread::exception_pc_offset()), NULL_WORD);
356 #endif
357 // Clear the exception oop so GC no longer processes it as a root.
358 __ movptr(Address(r15_thread, JavaThread::exception_oop_offset()), NULL_WORD);
359
360 // rax: exception oop
361 // r8: exception handler
362 // rdx: exception pc
363 // Jump to handler
364
365 __ jmp(r8);
366
367 // Make sure all code is generated
368 masm->flush();
369
370 SCCache::store_exception_blob(&buffer, pc_offset);
371 // Set exception blob
372 return ExceptionBlob::create(&buffer, oop_maps, SimpleRuntimeFrame::framesize >> 1);
373 }
374 #endif // COMPILER2
|