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