summaryrefslogtreecommitdiffstats
path: root/runtime/mirror/throwable.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/mirror/throwable.cc')
-rw-r--r--runtime/mirror/throwable.cc34
1 files changed, 23 insertions, 11 deletions
diff --git a/runtime/mirror/throwable.cc b/runtime/mirror/throwable.cc
index 782b9c0..1c21edb 100644
--- a/runtime/mirror/throwable.cc
+++ b/runtime/mirror/throwable.cc
@@ -71,9 +71,18 @@ bool Throwable::IsCheckedException() {
int32_t Throwable::GetStackDepth() {
Object* stack_state = GetStackState();
- if (stack_state == nullptr || !stack_state->IsObjectArray()) return -1;
- ObjectArray<Object>* method_trace = down_cast<ObjectArray<Object>*>(stack_state);
- return method_trace->GetLength() - 1;
+ if (stack_state == nullptr) {
+ return -1;
+ }
+ if (!stack_state->IsIntArray() && !stack_state->IsLongArray()) {
+ return -1;
+ }
+ mirror::PointerArray* method_trace = down_cast<mirror::PointerArray*>(stack_state->AsArray());
+ int32_t array_len = method_trace->GetLength();
+ // The format is [method pointers][pcs] so the depth is half the length (see method
+ // BuildInternalStackTraceVisitor::Init).
+ CHECK_EQ(array_len % 2, 0);
+ return array_len / 2;
}
std::string Throwable::Dump() {
@@ -86,17 +95,21 @@ std::string Throwable::Dump() {
result += "\n";
Object* stack_state = GetStackState();
// check stack state isn't missing or corrupt
- if (stack_state != nullptr && stack_state->IsObjectArray()) {
+ if (stack_state != nullptr &&
+ (stack_state->IsIntArray() || stack_state->IsLongArray())) {
// Decode the internal stack trace into the depth and method trace
- ObjectArray<Object>* method_trace = down_cast<ObjectArray<Object>*>(stack_state);
- int32_t depth = method_trace->GetLength() - 1;
- IntArray* pc_trace = down_cast<IntArray*>(method_trace->Get(depth));
+ // Format is [method pointers][pcs]
+ auto* method_trace = down_cast<mirror::PointerArray*>(stack_state->AsArray());
+ auto array_len = method_trace->GetLength();
+ CHECK_EQ(array_len % 2, 0);
+ const auto depth = array_len / 2;
if (depth == 0) {
result += "(Throwable with empty stack trace)";
} else {
+ auto ptr_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
for (int32_t i = 0; i < depth; ++i) {
- mirror::ArtMethod* method = down_cast<ArtMethod*>(method_trace->Get(i));
- uint32_t dex_pc = pc_trace->Get(i);
+ ArtMethod* method = method_trace->GetElementPtrSize<ArtMethod*>(i, ptr_size);
+ uintptr_t dex_pc = method_trace->GetElementPtrSize<uintptr_t>(i + depth, ptr_size);
int32_t line_number = method->GetLineNumFromDexPC(dex_pc);
const char* source_file = method->GetDeclaringClassSourceFile();
result += StringPrintf(" at %s (%s:%d)\n", PrettyMethod(method, true).c_str(),
@@ -108,8 +121,7 @@ std::string Throwable::Dump() {
if (stack_trace != nullptr && stack_trace->IsObjectArray()) {
CHECK_EQ(stack_trace->GetClass()->GetComponentType(),
StackTraceElement::GetStackTraceElement());
- ObjectArray<StackTraceElement>* ste_array =
- down_cast<ObjectArray<StackTraceElement>*>(stack_trace);
+ auto* ste_array = down_cast<ObjectArray<StackTraceElement>*>(stack_trace);
if (ste_array->GetLength() == 0) {
result += "(Throwable with empty stack trace)";
} else {