diff options
author | Sebastien Hertz <shertz@google.com> | 2014-05-23 08:59:42 +0200 |
---|---|---|
committer | Sebastien Hertz <shertz@google.com> | 2014-06-11 14:29:00 +0200 |
commit | 9f1020305292a21fd14a402b189c765a125226ab (patch) | |
tree | 6b730cbe56ded370d1b4293629826ad2c7b06f7f /runtime/thread.h | |
parent | bc72903b909f5147b8cb207f3e5d02a8ef85e4e7 (diff) | |
download | art-9f1020305292a21fd14a402b189c765a125226ab.zip art-9f1020305292a21fd14a402b189c765a125226ab.tar.gz art-9f1020305292a21fd14a402b189c765a125226ab.tar.bz2 |
Fix exception reporting from interpreter
To comply with JDWP exception report rules, we must report an exception at the
location of the throw (or the first instruction encountered after a native
call). To do this, we use the CatchLocationFinder visitor to look for a catch
handler until we reach a native frame or the top frame.
Because interpreter handles pending exception on a method-by-method basis, we
need a flag to remember we already reported the exception and avoid reporting
it multiple times when unwinding methods. The drawback is we need to maintain
the state of this flag. We clear it when the exception is cleared. In the case
we temporarily clear the exception (when finding a catch handler for instance),
we restore the flag to its previous value at the same time we restore the
pending exception.
Bump oat version to force recompilation because we modify Thread offsets.
Bug: 14402770
Change-Id: Ic059c58f80b2023b118038301f8f0a24f1e18241
Diffstat (limited to 'runtime/thread.h')
-rw-r--r-- | runtime/thread.h | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/runtime/thread.h b/runtime/thread.h index 5de54b3..bff9b52 100644 --- a/runtime/thread.h +++ b/runtime/thread.h @@ -329,6 +329,7 @@ class Thread { void ClearException() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { tlsPtr_.exception = nullptr; tlsPtr_.throw_location.Clear(); + SetExceptionReportedToInstrumentation(false); } // Find catch block and perform long jump to appropriate exception handle @@ -809,6 +810,14 @@ class Thread { tlsPtr_.rosalloc_runs[index] = run; } + bool IsExceptionReportedToInstrumentation() const { + return tls32_.is_exception_reported_to_instrumentation_; + } + + void SetExceptionReportedToInstrumentation(bool reported) { + tls32_.is_exception_reported_to_instrumentation_ = reported; + } + private: explicit Thread(bool daemon); ~Thread() LOCKS_EXCLUDED(Locks::mutator_lock_, @@ -911,7 +920,7 @@ class Thread { explicit tls_32bit_sized_values(bool is_daemon) : suspend_count(0), debug_suspend_count(0), thin_lock_thread_id(0), tid(0), daemon(is_daemon), throwing_OutOfMemoryError(false), no_thread_suspension(0), - thread_exit_check_count(0) { + thread_exit_check_count(0), is_exception_reported_to_instrumentation_(false) { } union StateAndFlags state_and_flags; @@ -947,6 +956,10 @@ class Thread { // How many times has our pthread key's destructor been called? uint32_t thread_exit_check_count; + + // When true this field indicates that the exception associated with this thread has already + // been reported to instrumentation. + bool32_t is_exception_reported_to_instrumentation_; } tls32_; struct PACKED(8) tls_64bit_sized_values { |