352 // set pending exception 353 __ verify_oop(rax); 354 __ movptr(Address(rcx, Thread::pending_exception_offset()), rax ); 355 __ lea(Address(rcx, Thread::exception_file_offset ()), 356 ExternalAddress((address)__FILE__)); 357 __ movl(Address(rcx, Thread::exception_line_offset ()), __LINE__ ); 358 // complete return to VM 359 assert(StubRoutines::_call_stub_return_address != NULL, "_call_stub_return_address must have been generated before"); 360 __ jump(RuntimeAddress(StubRoutines::_call_stub_return_address)); 361 362 return start; 363 } 364 365 366 //------------------------------------------------------------------------------------------------------------------------ 367 // Continuation point for runtime calls returning with a pending exception. 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. 370 // 371 // Contract with Java-level exception handlers: 372 // rax,: exception 373 // rdx: throwing pc 374 // 375 // NOTE: At entry of this stub, exception-pc must be on stack !! 376 377 address generate_forward_exception() { 378 StubCodeMark mark(this, "StubRoutines", "forward exception"); 379 address start = __ pc(); 380 381 // Upon entry, the sp points to the return address returning into Java 382 // (interpreted or compiled) code; i.e., the return address becomes the 383 // throwing pc. 384 // 385 // Arguments pushed before the runtime call are still on the stack but 386 // the exception handler will reset the stack pointer -> ignore them. 387 // A potential result in registers can be ignored as well. 388 389 #ifdef ASSERT 390 // make sure this code is only executed if there is a pending exception 391 { Label L; 392 __ get_thread(rcx); 393 __ cmpptr(Address(rcx, Thread::pending_exception_offset()), (int32_t)NULL_WORD); 394 __ jcc(Assembler::notEqual, L); 395 __ stop("StubRoutines::forward exception: no pending exception (1)"); 396 __ bind(L); 397 } 398 #endif 399 400 // compute exception handler into rbx, 401 __ movptr(rax, Address(rsp, 0)); 402 BLOCK_COMMENT("call exception_handler_for_return_address"); 403 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), rax); 404 __ mov(rbx, rax); 405 406 // setup rax, & rdx, remove return address & clear pending exception 407 __ get_thread(rcx); 408 __ pop(rdx); 409 __ movptr(rax, Address(rcx, Thread::pending_exception_offset())); 410 __ movptr(Address(rcx, Thread::pending_exception_offset()), NULL_WORD); 411 412 #ifdef ASSERT 413 // make sure exception is set 414 { Label L; 415 __ testptr(rax, rax); 416 __ jcc(Assembler::notEqual, L); 417 __ stop("StubRoutines::forward exception: no pending exception (2)"); 418 __ bind(L); 419 } 420 #endif 421 422 // continue at exception handler (return address removed) 423 // rax,: exception 424 // rbx,: exception handler 425 // rdx: throwing pc 426 __ verify_oop(rax); 427 __ jmp(rbx); 428 429 return start; 430 } 431 432 433 //---------------------------------------------------------------------------------------------------- 434 // Support for jint Atomic::xchg(jint exchange_value, volatile jint* dest) 435 // 436 // xchg exists as far back as 8086, lock needed for MP only 437 // Stack layout immediately after call: 438 // 439 // 0 [ret addr ] <--- rsp 440 // 1 [ ex ] 441 // 2 [ dest ] 442 // 443 // Result: *dest <- ex, return (old *dest) 444 // 445 // Note: win32 does not currently use this code 446 447 address generate_atomic_xchg() { | 352 // set pending exception 353 __ verify_oop(rax); 354 __ movptr(Address(rcx, Thread::pending_exception_offset()), rax ); 355 __ lea(Address(rcx, Thread::exception_file_offset ()), 356 ExternalAddress((address)__FILE__)); 357 __ movl(Address(rcx, Thread::exception_line_offset ()), __LINE__ ); 358 // complete return to VM 359 assert(StubRoutines::_call_stub_return_address != NULL, "_call_stub_return_address must have been generated before"); 360 __ jump(RuntimeAddress(StubRoutines::_call_stub_return_address)); 361 362 return start; 363 } 364 365 366 //------------------------------------------------------------------------------------------------------------------------ 367 // Continuation point for runtime calls returning with a pending exception. 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. 370 // 371 // Contract with Java-level exception handlers: 372 // rax: exception 373 // rdx: throwing pc 374 // 375 // NOTE: At entry of this stub, exception-pc must be on stack !! 376 377 address generate_forward_exception() { 378 StubCodeMark mark(this, "StubRoutines", "forward exception"); 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; 386 387 // Upon entry, the sp points to the return address returning into Java 388 // (interpreted or compiled) code; i.e., the return address becomes the 389 // throwing pc. 390 // 391 // Arguments pushed before the runtime call are still on the stack but 392 // the exception handler will reset the stack pointer -> ignore them. 393 // A potential result in registers can be ignored as well. 394 395 #ifdef ASSERT 396 // make sure this code is only executed if there is a pending exception 397 { Label L; 398 __ get_thread(thread); 399 __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); 400 __ jcc(Assembler::notEqual, L); 401 __ stop("StubRoutines::forward exception: no pending exception (1)"); 402 __ bind(L); 403 } 404 #endif 405 406 // compute exception handler into rbx, 407 __ get_thread(thread); 408 __ movptr(exception_pc, Address(rsp, 0)); 409 BLOCK_COMMENT("call exception_handler_for_return_address"); 410 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), thread, exception_pc); 411 __ mov(handler_addr, rax); 412 413 // setup rax & rdx, remove return address & clear pending exception 414 __ get_thread(thread); 415 __ pop(exception_pc); 416 __ movptr(exception_oop, Address(thread, Thread::pending_exception_offset())); 417 __ movptr(Address(thread, Thread::pending_exception_offset()), NULL_WORD); 418 419 #ifdef ASSERT 420 // make sure exception is set 421 { Label L; 422 __ testptr(exception_oop, exception_oop); 423 __ jcc(Assembler::notEqual, L); 424 __ stop("StubRoutines::forward exception: no pending exception (2)"); 425 __ bind(L); 426 } 427 #endif 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 436 // continue at exception handler (return address removed) 437 // rax: exception 438 // rbx: exception handler 439 // rdx: throwing pc 440 __ jmp(handler_addr); 441 442 return start; 443 } 444 445 446 //---------------------------------------------------------------------------------------------------- 447 // Support for jint Atomic::xchg(jint exchange_value, volatile jint* dest) 448 // 449 // xchg exists as far back as 8086, lock needed for MP only 450 // Stack layout immediately after call: 451 // 452 // 0 [ret addr ] <--- rsp 453 // 1 [ ex ] 454 // 2 [ dest ] 455 // 456 // Result: *dest <- ex, return (old *dest) 457 // 458 // Note: win32 does not currently use this code 459 460 address generate_atomic_xchg() { |