ART: Target-dependent stack overflow, less check elision
Refactor the separate stack overflow reserved sizes from thread.h
into instruction_set.h and make sure they're used in the compiler.
Refactor the decision on when to elide stack overflow checks:
especially with large interpreter stack frames, it is not a good
idea to elide checks when the frame size is even close to the
reserved size. Currently enforce checks when the frame size is
>= 2KB, but make sure that frame sizes 1KB and below will elide
the checks (number from experience).
Bug: 15728765
Change-Id: I016bfd3d8218170cbccbd123ed5e2203db167c06
diff --git a/runtime/thread.h b/runtime/thread.h
index bff9b52..7cd86de 100644
--- a/runtime/thread.h
+++ b/runtime/thread.h
@@ -33,6 +33,7 @@
#include "gc/allocator/rosalloc.h"
#include "globals.h"
#include "handle_scope.h"
+#include "instruction_set.h"
#include "jvalue.h"
#include "object_callbacks.h"
#include "offsets.h"
@@ -94,28 +95,8 @@
class Thread {
public:
- // Space to throw a StackOverflowError in.
- // TODO: shrink reserved space, in particular for 64bit.
-#if defined(__x86_64__)
- static constexpr size_t kStackOverflowReservedBytes = 32 * KB;
-#elif defined(__aarch64__)
- // Worst-case, we would need about 2.6x the amount of x86_64 for many more registers.
- // But this one works rather well.
- static constexpr size_t kStackOverflowReservedBytes = 32 * KB;
-#elif defined(__i386__)
- // TODO: Bumped to workaround regression (http://b/14982147) Specifically to fix:
- // test-art-host-run-test-interpreter-018-stack-overflow
- // test-art-host-run-test-interpreter-107-int-math2
- static constexpr size_t kStackOverflowReservedBytes = 24 * KB;
-#else
- static constexpr size_t kStackOverflowReservedBytes = 16 * KB;
-#endif
// How much of the reserved bytes is reserved for incoming signals.
static constexpr size_t kStackOverflowSignalReservedBytes = 2 * KB;
- // How much of the reserved bytes we may temporarily use during stack overflow checks as an
- // optimization.
- static constexpr size_t kStackOverflowReservedUsableBytes =
- kStackOverflowReservedBytes - kStackOverflowSignalReservedBytes;
// For implicit overflow checks we reserve an extra piece of memory at the bottom
// of the stack (lowest memory). The higher portion of the memory
@@ -123,7 +104,7 @@
// throwing the StackOverflow exception.
static constexpr size_t kStackOverflowProtectedSize = 16 * KB;
static constexpr size_t kStackOverflowImplicitCheckSize = kStackOverflowProtectedSize +
- kStackOverflowReservedBytes;
+ kRuntimeStackOverflowReservedBytes;
// Creates a new native thread corresponding to the given managed peer.
// Used to implement Thread.start.
@@ -585,7 +566,7 @@
// overflow region.
tlsPtr_.stack_end = tlsPtr_.stack_begin + kStackOverflowImplicitCheckSize;
} else {
- tlsPtr_.stack_end = tlsPtr_.stack_begin + kStackOverflowReservedBytes;
+ tlsPtr_.stack_end = tlsPtr_.stack_begin + kRuntimeStackOverflowReservedBytes;
}
}