summaryrefslogtreecommitdiffstats
path: root/runtime/stack.h
diff options
context:
space:
mode:
authorHiroshi Yamauchi <yamauchi@google.com>2014-08-13 11:12:22 -0700
committerHiroshi Yamauchi <yamauchi@google.com>2014-08-13 20:46:10 -0700
commit649278cec7119cdd1bea3d0b710dbb2aa7c650b6 (patch)
tree6b5e08abee97e8af1ee5635488e6476d3fb3dc15 /runtime/stack.h
parent99c251bbd225dd97d0deece29559a430b12a0b66 (diff)
downloadart-649278cec7119cdd1bea3d0b710dbb2aa7c650b6.zip
art-649278cec7119cdd1bea3d0b710dbb2aa7c650b6.tar.gz
art-649278cec7119cdd1bea3d0b710dbb2aa7c650b6.tar.bz2
More efficient stack walk in exception throwing.
In the exception handling code, we currently walk down the stack twice, once to get the stack height which we use to compute frame IDs (the bottom frame is zero), and once more to find the catch block to jump to. For a deep stack, this could result in very slow exception handling. That is, if have a lot of finally or catch blocks that we end up jumping to in a deep stack, we need to do a lot of catch/rethrow chains. Since we'd need to walk down to the bottom each time to compute frames IDs in each catch/rethrow, we'd need to walk down O(N^2) frames at the worst case. Instead of frames IDs ((the bottom frame is zero), we will use the frame depth (the top frame is zero) and no longer need to walk down the stack just to get the stack height. We walk down O(N) frames. This was what was happening with code.google.gson.functional.CircularReferenceTest. With this change, the test run time went from ~120s down to ~3s on N5 and it no longer crashes due to the thread suspension timeout. Bug: 16800209 Change-Id: Ie815df1e3e8fb9d82e40685d4cc2b8838fd8aa07
Diffstat (limited to 'runtime/stack.h')
-rw-r--r--runtime/stack.h4
1 files changed, 4 insertions, 0 deletions
diff --git a/runtime/stack.h b/runtime/stack.h
index 578f569..e58caee 100644
--- a/runtime/stack.h
+++ b/runtime/stack.h
@@ -553,6 +553,10 @@ class StackVisitor {
return num_frames_;
}
+ size_t GetFrameDepth() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return cur_depth_;
+ }
+
// Get the method and dex pc immediately after the one that's currently being visited.
bool GetNextMethodAndDexPc(mirror::ArtMethod** next_method, uint32_t* next_dex_pc)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);