提交 660cd8f2 编写于 作者: T twisti

6941529: SharedRuntime::raw_exception_handler_for_return_address must reset...

6941529: SharedRuntime::raw_exception_handler_for_return_address must reset thread MethodHandle flag
Summary: During testing a bug was hit when an exception returned to the interpreter and the SP was wrong.
Reviewed-by: kvn, never
上级 7b4f0424
...@@ -781,7 +781,7 @@ void Runtime1::generate_unwind_exception(StubAssembler *sasm) { ...@@ -781,7 +781,7 @@ void Runtime1::generate_unwind_exception(StubAssembler *sasm) {
// Restore SP from BP if the exception PC is a MethodHandle call site. // Restore SP from BP if the exception PC is a MethodHandle call site.
NOT_LP64(__ get_thread(thread);) NOT_LP64(__ get_thread(thread);)
__ cmpl(Address(thread, JavaThread::is_method_handle_exception_offset()), 0); __ cmpl(Address(thread, JavaThread::is_method_handle_return_offset()), 0);
__ cmovptr(Assembler::notEqual, rsp, rbp); __ cmovptr(Assembler::notEqual, rsp, rbp);
// continue at exception handler (return address removed) // continue at exception handler (return address removed)
......
...@@ -115,8 +115,8 @@ void OptoRuntime::generate_exception_blob() { ...@@ -115,8 +115,8 @@ void OptoRuntime::generate_exception_blob() {
// rax: exception handler for given <exception oop/exception pc> // rax: exception handler for given <exception oop/exception pc>
// Restore SP from BP if the exception PC is a MethodHandle call. // Restore SP from BP if the exception PC is a MethodHandle call site.
__ cmpl(Address(rcx, JavaThread::is_method_handle_exception_offset()), 0); __ cmpl(Address(rcx, JavaThread::is_method_handle_return_offset()), 0);
__ cmovptr(Assembler::notEqual, rsp, rbp); __ cmovptr(Assembler::notEqual, rsp, rbp);
// We have a handler in rax, (could be deopt blob) // We have a handler in rax, (could be deopt blob)
......
...@@ -3328,8 +3328,8 @@ void OptoRuntime::generate_exception_blob() { ...@@ -3328,8 +3328,8 @@ void OptoRuntime::generate_exception_blob() {
// rax: exception handler // rax: exception handler
// Restore SP from BP if the exception PC is a MethodHandle call. // Restore SP from BP if the exception PC is a MethodHandle call site.
__ cmpl(Address(r15_thread, JavaThread::is_method_handle_exception_offset()), 0); __ cmpl(Address(r15_thread, JavaThread::is_method_handle_return_offset()), 0);
__ cmovptr(Assembler::notEqual, rsp, rbp); __ cmovptr(Assembler::notEqual, rsp, rbp);
// We have a handler in rax (could be deopt blob). // We have a handler in rax (could be deopt blob).
......
...@@ -430,7 +430,7 @@ class StubGenerator: public StubCodeGenerator { ...@@ -430,7 +430,7 @@ class StubGenerator: public StubCodeGenerator {
__ verify_oop(exception_oop); __ verify_oop(exception_oop);
// Restore SP from BP if the exception PC is a MethodHandle call site. // Restore SP from BP if the exception PC is a MethodHandle call site.
__ cmpl(Address(thread, JavaThread::is_method_handle_exception_offset()), 0); __ cmpl(Address(thread, JavaThread::is_method_handle_return_offset()), 0);
__ cmovptr(Assembler::notEqual, rsp, rbp); __ cmovptr(Assembler::notEqual, rsp, rbp);
// continue at exception handler (return address removed) // continue at exception handler (return address removed)
......
...@@ -865,7 +865,7 @@ JRT_ENTRY_NO_ASYNC(address, OptoRuntime::handle_exception_C_helper(JavaThread* t ...@@ -865,7 +865,7 @@ JRT_ENTRY_NO_ASYNC(address, OptoRuntime::handle_exception_C_helper(JavaThread* t
thread->set_exception_stack_size(0); thread->set_exception_stack_size(0);
// Check if the exception PC is a MethodHandle call site. // Check if the exception PC is a MethodHandle call site.
thread->set_is_method_handle_exception(nm->is_method_handle_return(pc)); thread->set_is_method_handle_return(nm->is_method_handle_return(pc));
} }
// Restore correct return pc. Was saved above. // Restore correct return pc. Was saved above.
......
...@@ -259,13 +259,16 @@ JRT_END ...@@ -259,13 +259,16 @@ JRT_END
address SharedRuntime::raw_exception_handler_for_return_address(JavaThread* thread, address return_address) { address SharedRuntime::raw_exception_handler_for_return_address(JavaThread* thread, address return_address) {
assert(frame::verify_return_pc(return_address), "must be a return pc"); assert(frame::verify_return_pc(return_address), "must be a return pc");
// Reset MethodHandle flag.
thread->set_is_method_handle_return(false);
// the fastest case first // the fastest case first
CodeBlob* blob = CodeCache::find_blob(return_address); CodeBlob* blob = CodeCache::find_blob(return_address);
if (blob != NULL && blob->is_nmethod()) { if (blob != NULL && blob->is_nmethod()) {
nmethod* code = (nmethod*)blob; nmethod* code = (nmethod*)blob;
assert(code != NULL, "nmethod must be present"); assert(code != NULL, "nmethod must be present");
// Check if the return address is a MethodHandle call site. // Check if the return address is a MethodHandle call site.
thread->set_is_method_handle_exception(code->is_method_handle_return(return_address)); thread->set_is_method_handle_return(code->is_method_handle_return(return_address));
// native nmethods don't have exception handlers // native nmethods don't have exception handlers
assert(!code->is_native_method(), "no exception handler"); assert(!code->is_native_method(), "no exception handler");
assert(code->header_begin() != code->exception_begin(), "no exception handler"); assert(code->header_begin() != code->exception_begin(), "no exception handler");
...@@ -292,7 +295,7 @@ address SharedRuntime::raw_exception_handler_for_return_address(JavaThread* thre ...@@ -292,7 +295,7 @@ address SharedRuntime::raw_exception_handler_for_return_address(JavaThread* thre
nmethod* code = (nmethod*)blob; nmethod* code = (nmethod*)blob;
assert(code != NULL, "nmethod must be present"); assert(code != NULL, "nmethod must be present");
// Check if the return address is a MethodHandle call site. // Check if the return address is a MethodHandle call site.
thread->set_is_method_handle_exception(code->is_method_handle_return(return_address)); thread->set_is_method_handle_return(code->is_method_handle_return(return_address));
assert(code->header_begin() != code->exception_begin(), "no exception handler"); assert(code->header_begin() != code->exception_begin(), "no exception handler");
return code->exception_begin(); return code->exception_begin();
} }
......
...@@ -772,7 +772,7 @@ class JavaThread: public Thread { ...@@ -772,7 +772,7 @@ class JavaThread: public Thread {
volatile address _exception_pc; // PC where exception happened volatile address _exception_pc; // PC where exception happened
volatile address _exception_handler_pc; // PC for handler of exception volatile address _exception_handler_pc; // PC for handler of exception
volatile int _exception_stack_size; // Size of frame where exception happened volatile int _exception_stack_size; // Size of frame where exception happened
volatile int _is_method_handle_exception; // True if the current exception PC is at a MethodHandle call. volatile int _is_method_handle_return; // true (== 1) if the current exception PC is a MethodHandle call site.
// support for compilation // support for compilation
bool _is_compiling; // is true if a compilation is active inthis thread (one compilation per thread possible) bool _is_compiling; // is true if a compilation is active inthis thread (one compilation per thread possible)
...@@ -1108,13 +1108,13 @@ class JavaThread: public Thread { ...@@ -1108,13 +1108,13 @@ class JavaThread: public Thread {
int exception_stack_size() const { return _exception_stack_size; } int exception_stack_size() const { return _exception_stack_size; }
address exception_pc() const { return _exception_pc; } address exception_pc() const { return _exception_pc; }
address exception_handler_pc() const { return _exception_handler_pc; } address exception_handler_pc() const { return _exception_handler_pc; }
int is_method_handle_exception() const { return _is_method_handle_exception; } bool is_method_handle_return() const { return _is_method_handle_return == 1; }
void set_exception_oop(oop o) { _exception_oop = o; } void set_exception_oop(oop o) { _exception_oop = o; }
void set_exception_pc(address a) { _exception_pc = a; } void set_exception_pc(address a) { _exception_pc = a; }
void set_exception_handler_pc(address a) { _exception_handler_pc = a; } void set_exception_handler_pc(address a) { _exception_handler_pc = a; }
void set_exception_stack_size(int size) { _exception_stack_size = size; } void set_exception_stack_size(int size) { _exception_stack_size = size; }
void set_is_method_handle_exception(int value) { _is_method_handle_exception = value; } void set_is_method_handle_return(bool value) { _is_method_handle_return = value ? 1 : 0; }
// Stack overflow support // Stack overflow support
inline size_t stack_available(address cur_sp); inline size_t stack_available(address cur_sp);
...@@ -1188,7 +1188,7 @@ class JavaThread: public Thread { ...@@ -1188,7 +1188,7 @@ class JavaThread: public Thread {
static ByteSize exception_pc_offset() { return byte_offset_of(JavaThread, _exception_pc ); } static ByteSize exception_pc_offset() { return byte_offset_of(JavaThread, _exception_pc ); }
static ByteSize exception_handler_pc_offset() { return byte_offset_of(JavaThread, _exception_handler_pc); } static ByteSize exception_handler_pc_offset() { return byte_offset_of(JavaThread, _exception_handler_pc); }
static ByteSize exception_stack_size_offset() { return byte_offset_of(JavaThread, _exception_stack_size); } static ByteSize exception_stack_size_offset() { return byte_offset_of(JavaThread, _exception_stack_size); }
static ByteSize is_method_handle_exception_offset() { return byte_offset_of(JavaThread, _is_method_handle_exception); } static ByteSize is_method_handle_return_offset() { return byte_offset_of(JavaThread, _is_method_handle_return); }
static ByteSize stack_guard_state_offset() { return byte_offset_of(JavaThread, _stack_guard_state ); } static ByteSize stack_guard_state_offset() { return byte_offset_of(JavaThread, _stack_guard_state ); }
static ByteSize suspend_flags_offset() { return byte_offset_of(JavaThread, _suspend_flags ); } static ByteSize suspend_flags_offset() { return byte_offset_of(JavaThread, _suspend_flags ); }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册