Mercurial > hg > graal-jvmci-8
comparison src/cpu/x86/vm/stubGenerator_x86_32.cpp @ 1295:3cf667df43ef
6919934: JSR 292 needs to support x86 C1
Summary: This implements JSR 292 support for C1 x86.
Reviewed-by: never, jrose, kvn
author | twisti |
---|---|
date | Tue, 09 Mar 2010 20:16:19 +0100 |
parents | 776fb94f33cc |
children | 9eba43136cb5 |
comparison
equal
deleted
inserted
replaced
1293:51db1e4b379d | 1295:3cf667df43ef |
---|---|
367 // Continuation point for runtime calls returning with a pending exception. | 367 // Continuation point for runtime calls returning with a pending exception. |
368 // The pending exception check happened in the runtime or native call stub. | 368 // The pending exception check happened in the runtime or native call stub. |
369 // The pending exception in Thread is converted into a Java-level exception. | 369 // The pending exception in Thread is converted into a Java-level exception. |
370 // | 370 // |
371 // Contract with Java-level exception handlers: | 371 // Contract with Java-level exception handlers: |
372 // rax,: exception | 372 // rax: exception |
373 // rdx: throwing pc | 373 // rdx: throwing pc |
374 // | 374 // |
375 // NOTE: At entry of this stub, exception-pc must be on stack !! | 375 // NOTE: At entry of this stub, exception-pc must be on stack !! |
376 | 376 |
377 address generate_forward_exception() { | 377 address generate_forward_exception() { |
378 StubCodeMark mark(this, "StubRoutines", "forward exception"); | 378 StubCodeMark mark(this, "StubRoutines", "forward exception"); |
379 address start = __ pc(); | 379 address start = __ pc(); |
380 const Register thread = rcx; | |
381 | |
382 // other registers used in this stub | |
383 const Register exception_oop = rax; | |
384 const Register handler_addr = rbx; | |
385 const Register exception_pc = rdx; | |
380 | 386 |
381 // Upon entry, the sp points to the return address returning into Java | 387 // Upon entry, the sp points to the return address returning into Java |
382 // (interpreted or compiled) code; i.e., the return address becomes the | 388 // (interpreted or compiled) code; i.e., the return address becomes the |
383 // throwing pc. | 389 // throwing pc. |
384 // | 390 // |
387 // A potential result in registers can be ignored as well. | 393 // A potential result in registers can be ignored as well. |
388 | 394 |
389 #ifdef ASSERT | 395 #ifdef ASSERT |
390 // make sure this code is only executed if there is a pending exception | 396 // make sure this code is only executed if there is a pending exception |
391 { Label L; | 397 { Label L; |
392 __ get_thread(rcx); | 398 __ get_thread(thread); |
393 __ cmpptr(Address(rcx, Thread::pending_exception_offset()), (int32_t)NULL_WORD); | 399 __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); |
394 __ jcc(Assembler::notEqual, L); | 400 __ jcc(Assembler::notEqual, L); |
395 __ stop("StubRoutines::forward exception: no pending exception (1)"); | 401 __ stop("StubRoutines::forward exception: no pending exception (1)"); |
396 __ bind(L); | 402 __ bind(L); |
397 } | 403 } |
398 #endif | 404 #endif |
399 | 405 |
400 // compute exception handler into rbx, | 406 // compute exception handler into rbx, |
401 __ movptr(rax, Address(rsp, 0)); | 407 __ get_thread(thread); |
408 __ movptr(exception_pc, Address(rsp, 0)); | |
402 BLOCK_COMMENT("call exception_handler_for_return_address"); | 409 BLOCK_COMMENT("call exception_handler_for_return_address"); |
403 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), rax); | 410 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), thread, exception_pc); |
404 __ mov(rbx, rax); | 411 __ mov(handler_addr, rax); |
405 | 412 |
406 // setup rax, & rdx, remove return address & clear pending exception | 413 // setup rax & rdx, remove return address & clear pending exception |
407 __ get_thread(rcx); | 414 __ get_thread(thread); |
408 __ pop(rdx); | 415 __ pop(exception_pc); |
409 __ movptr(rax, Address(rcx, Thread::pending_exception_offset())); | 416 __ movptr(exception_oop, Address(thread, Thread::pending_exception_offset())); |
410 __ movptr(Address(rcx, Thread::pending_exception_offset()), NULL_WORD); | 417 __ movptr(Address(thread, Thread::pending_exception_offset()), NULL_WORD); |
411 | 418 |
412 #ifdef ASSERT | 419 #ifdef ASSERT |
413 // make sure exception is set | 420 // make sure exception is set |
414 { Label L; | 421 { Label L; |
415 __ testptr(rax, rax); | 422 __ testptr(exception_oop, exception_oop); |
416 __ jcc(Assembler::notEqual, L); | 423 __ jcc(Assembler::notEqual, L); |
417 __ stop("StubRoutines::forward exception: no pending exception (2)"); | 424 __ stop("StubRoutines::forward exception: no pending exception (2)"); |
418 __ bind(L); | 425 __ bind(L); |
419 } | 426 } |
420 #endif | 427 #endif |
421 | 428 |
429 // Verify that there is really a valid exception in RAX. | |
430 __ verify_oop(exception_oop); | |
431 | |
432 // Restore SP from BP if the exception PC is a MethodHandle call site. | |
433 __ cmpl(Address(thread, JavaThread::is_method_handle_exception_offset()), 0); | |
434 __ cmovptr(Assembler::notEqual, rsp, rbp); | |
435 | |
422 // continue at exception handler (return address removed) | 436 // continue at exception handler (return address removed) |
423 // rax,: exception | 437 // rax: exception |
424 // rbx,: exception handler | 438 // rbx: exception handler |
425 // rdx: throwing pc | 439 // rdx: throwing pc |
426 __ verify_oop(rax); | 440 __ jmp(handler_addr); |
427 __ jmp(rbx); | |
428 | 441 |
429 return start; | 442 return start; |
430 } | 443 } |
431 | 444 |
432 | 445 |