From 660cd8f2bf58148f385ce120c9af512926e53254 Mon Sep 17 00:00:00 2001 From: twisti Date: Thu, 8 Apr 2010 10:55:40 +0200 Subject: [PATCH] 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 --- src/cpu/x86/vm/c1_Runtime1_x86.cpp | 2 +- src/cpu/x86/vm/runtime_x86_32.cpp | 4 ++-- src/cpu/x86/vm/sharedRuntime_x86_64.cpp | 4 ++-- src/cpu/x86/vm/stubGenerator_x86_32.cpp | 2 +- src/share/vm/opto/runtime.cpp | 2 +- src/share/vm/runtime/sharedRuntime.cpp | 7 +++++-- src/share/vm/runtime/thread.hpp | 8 ++++---- 7 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/cpu/x86/vm/c1_Runtime1_x86.cpp b/src/cpu/x86/vm/c1_Runtime1_x86.cpp index e3bf6fdae..ff3e506ac 100644 --- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp +++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp @@ -781,7 +781,7 @@ void Runtime1::generate_unwind_exception(StubAssembler *sasm) { // Restore SP from BP if the exception PC is a MethodHandle call site. 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); // continue at exception handler (return address removed) diff --git a/src/cpu/x86/vm/runtime_x86_32.cpp b/src/cpu/x86/vm/runtime_x86_32.cpp index 428d239d4..3c220d7f6 100644 --- a/src/cpu/x86/vm/runtime_x86_32.cpp +++ b/src/cpu/x86/vm/runtime_x86_32.cpp @@ -115,8 +115,8 @@ void OptoRuntime::generate_exception_blob() { // rax: exception handler for given - // Restore SP from BP if the exception PC is a MethodHandle call. - __ cmpl(Address(rcx, JavaThread::is_method_handle_exception_offset()), 0); + // Restore SP from BP if the exception PC is a MethodHandle call site. + __ cmpl(Address(rcx, JavaThread::is_method_handle_return_offset()), 0); __ cmovptr(Assembler::notEqual, rsp, rbp); // We have a handler in rax, (could be deopt blob) diff --git a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp index e09b91d38..9fa01e4bd 100644 --- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp +++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp @@ -3328,8 +3328,8 @@ void OptoRuntime::generate_exception_blob() { // rax: exception handler - // Restore SP from BP if the exception PC is a MethodHandle call. - __ cmpl(Address(r15_thread, JavaThread::is_method_handle_exception_offset()), 0); + // Restore SP from BP if the exception PC is a MethodHandle call site. + __ cmpl(Address(r15_thread, JavaThread::is_method_handle_return_offset()), 0); __ cmovptr(Assembler::notEqual, rsp, rbp); // We have a handler in rax (could be deopt blob). diff --git a/src/cpu/x86/vm/stubGenerator_x86_32.cpp b/src/cpu/x86/vm/stubGenerator_x86_32.cpp index 68872420f..ccb8bf0a5 100644 --- a/src/cpu/x86/vm/stubGenerator_x86_32.cpp +++ b/src/cpu/x86/vm/stubGenerator_x86_32.cpp @@ -430,7 +430,7 @@ class StubGenerator: public StubCodeGenerator { __ verify_oop(exception_oop); // 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); // continue at exception handler (return address removed) diff --git a/src/share/vm/opto/runtime.cpp b/src/share/vm/opto/runtime.cpp index d293f0511..c87d654c1 100644 --- a/src/share/vm/opto/runtime.cpp +++ b/src/share/vm/opto/runtime.cpp @@ -865,7 +865,7 @@ JRT_ENTRY_NO_ASYNC(address, OptoRuntime::handle_exception_C_helper(JavaThread* t thread->set_exception_stack_size(0); // 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. diff --git a/src/share/vm/runtime/sharedRuntime.cpp b/src/share/vm/runtime/sharedRuntime.cpp index d09579b77..b2c5c43c1 100644 --- a/src/share/vm/runtime/sharedRuntime.cpp +++ b/src/share/vm/runtime/sharedRuntime.cpp @@ -259,13 +259,16 @@ JRT_END 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"); + // Reset MethodHandle flag. + thread->set_is_method_handle_return(false); + // the fastest case first CodeBlob* blob = CodeCache::find_blob(return_address); if (blob != NULL && blob->is_nmethod()) { nmethod* code = (nmethod*)blob; assert(code != NULL, "nmethod must be present"); // 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 assert(!code->is_native_method(), "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 nmethod* code = (nmethod*)blob; assert(code != NULL, "nmethod must be present"); // 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"); return code->exception_begin(); } diff --git a/src/share/vm/runtime/thread.hpp b/src/share/vm/runtime/thread.hpp index 49112fe23..8e65698cd 100644 --- a/src/share/vm/runtime/thread.hpp +++ b/src/share/vm/runtime/thread.hpp @@ -772,7 +772,7 @@ class JavaThread: public Thread { volatile address _exception_pc; // PC where exception happened volatile address _exception_handler_pc; // PC for handler of exception 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 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 { int exception_stack_size() const { return _exception_stack_size; } address exception_pc() const { return _exception_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_pc(address a) { _exception_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_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 inline size_t stack_available(address cur_sp); @@ -1188,7 +1188,7 @@ class JavaThread: public Thread { 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_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 suspend_flags_offset() { return byte_offset_of(JavaThread, _suspend_flags ); } -- GitLab