Change MethodHelper to use a Handle.
Added ConstHandle to help prevent errors where you modify the value
stored in the handle of the caller. Also fixed compaction bugs
related to not knowing MethodHelper::GetReturnType can resolve types.
This bug was present in interpreter RETURN_OBJECT.
Bug: 13077697
Change-Id: I71f964d4d810ab4debda1a09bc968af8f3c874a3
diff --git a/runtime/mirror/art_method-inl.h b/runtime/mirror/art_method-inl.h
index 5f4619b..8fcacc2 100644
--- a/runtime/mirror/art_method-inl.h
+++ b/runtime/mirror/art_method-inl.h
@@ -295,7 +295,9 @@
if (UNLIKELY(entry_point == runtime->GetClassLinker()->GetQuickGenericJniTrampoline())) {
// Generic JNI frame.
DCHECK(IsNative());
- uint32_t handle_refs = MethodHelper(this).GetNumberOfReferenceArgsWithoutReceiver() + 1;
+ StackHandleScope<1> hs(Thread::Current());
+ uint32_t handle_refs =
+ MethodHelper(hs.NewHandle(this)).GetNumberOfReferenceArgsWithoutReceiver() + 1;
size_t scope_size = HandleScope::SizeOf(handle_refs);
QuickMethodFrameInfo callee_info = runtime->GetCalleeSaveMethodFrameInfo(Runtime::kRefsAndArgs);
@@ -314,10 +316,143 @@
inline QuickMethodFrameInfo ArtMethod::GetQuickFrameInfo(const void* code_pointer) {
DCHECK(code_pointer != nullptr);
- DCHECK(code_pointer == GetQuickOatCodePointer());
+ DCHECK_EQ(code_pointer, GetQuickOatCodePointer());
return reinterpret_cast<const OatQuickMethodHeader*>(code_pointer)[-1].frame_info_;
}
+inline const DexFile* ArtMethod::GetDexFile() {
+ return GetInterfaceMethodIfProxy()->GetDeclaringClass()->GetDexCache()->GetDexFile();
+}
+
+inline const char* ArtMethod::GetDeclaringClassDescriptor() {
+ mirror::ArtMethod* method = GetInterfaceMethodIfProxy();
+ uint32_t dex_method_idx = method->GetDexMethodIndex();
+ if (UNLIKELY(dex_method_idx == DexFile::kDexNoIndex)) {
+ return "<runtime method>";
+ }
+ const DexFile* dex_file = method->GetDexFile();
+ return dex_file->GetMethodDeclaringClassDescriptor(dex_file->GetMethodId(dex_method_idx));
+}
+
+inline const char* ArtMethod::GetShorty(uint32_t* out_length) {
+ mirror::ArtMethod* method = GetInterfaceMethodIfProxy();
+ const DexFile* dex_file = method->GetDexFile();
+ return dex_file->GetMethodShorty(dex_file->GetMethodId(method->GetDexMethodIndex()), out_length);
+}
+
+inline const Signature ArtMethod::GetSignature() {
+ mirror::ArtMethod* method = GetInterfaceMethodIfProxy();
+ uint32_t dex_method_idx = method->GetDexMethodIndex();
+ if (dex_method_idx != DexFile::kDexNoIndex) {
+ const DexFile* dex_file = method->GetDexFile();
+ return dex_file->GetMethodSignature(dex_file->GetMethodId(dex_method_idx));
+ }
+ return Signature::NoSignature();
+}
+
+inline const char* ArtMethod::GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ mirror::ArtMethod* method = GetInterfaceMethodIfProxy();
+ uint32_t dex_method_idx = method->GetDexMethodIndex();
+ if (LIKELY(dex_method_idx != DexFile::kDexNoIndex)) {
+ const DexFile* dex_file = method->GetDexFile();
+ return dex_file->GetMethodName(dex_file->GetMethodId(dex_method_idx));
+ }
+ Runtime* runtime = Runtime::Current();
+ if (method == runtime->GetResolutionMethod()) {
+ return "<runtime internal resolution method>";
+ } else if (method == runtime->GetImtConflictMethod()) {
+ return "<runtime internal imt conflict method>";
+ } else if (method == runtime->GetCalleeSaveMethod(Runtime::kSaveAll)) {
+ return "<runtime internal callee-save all registers method>";
+ } else if (method == runtime->GetCalleeSaveMethod(Runtime::kRefsOnly)) {
+ return "<runtime internal callee-save reference registers method>";
+ } else if (method == runtime->GetCalleeSaveMethod(Runtime::kRefsAndArgs)) {
+ return "<runtime internal callee-save reference and argument registers method>";
+ } else {
+ return "<unknown runtime internal method>";
+ }
+}
+
+inline const DexFile::CodeItem* ArtMethod::GetCodeItem() {
+ mirror::ArtMethod* method = GetInterfaceMethodIfProxy();
+ return method->GetDexFile()->GetCodeItem(method->GetCodeItemOffset());
+}
+
+inline bool ArtMethod::IsResolvedTypeIdx(uint16_t type_idx) {
+ mirror::ArtMethod* method = GetInterfaceMethodIfProxy();
+ return method->GetDexCacheResolvedTypes()->Get(type_idx) != nullptr;
+}
+
+inline int32_t ArtMethod::GetLineNumFromDexPC(uint32_t dex_pc) {
+ mirror::ArtMethod* method = GetInterfaceMethodIfProxy();
+ if (dex_pc == DexFile::kDexNoIndex) {
+ return method->IsNative() ? -2 : -1;
+ }
+ return method->GetDexFile()->GetLineNumFromPC(method, dex_pc);
+}
+
+inline const DexFile::ProtoId& ArtMethod::GetPrototype() {
+ mirror::ArtMethod* method = GetInterfaceMethodIfProxy();
+ const DexFile* dex_file = method->GetDexFile();
+ return dex_file->GetMethodPrototype(dex_file->GetMethodId(method->GetDexMethodIndex()));
+}
+
+inline const DexFile::TypeList* ArtMethod::GetParameterTypeList() {
+ mirror::ArtMethod* method = GetInterfaceMethodIfProxy();
+ const DexFile* dex_file = method->GetDexFile();
+ const DexFile::ProtoId& proto = dex_file->GetMethodPrototype(
+ dex_file->GetMethodId(method->GetDexMethodIndex()));
+ return dex_file->GetProtoParameters(proto);
+}
+
+inline const char* ArtMethod::GetDeclaringClassSourceFile() {
+ return GetInterfaceMethodIfProxy()->GetDeclaringClass()->GetSourceFile();
+}
+
+inline uint16_t ArtMethod::GetClassDefIndex() {
+ return GetInterfaceMethodIfProxy()->GetDeclaringClass()->GetDexClassDefIndex();
+}
+
+inline const DexFile::ClassDef& ArtMethod::GetClassDef() {
+ mirror::ArtMethod* method = GetInterfaceMethodIfProxy();
+ return method->GetDexFile()->GetClassDef(GetClassDefIndex());
+}
+
+inline const char* ArtMethod::GetReturnTypeDescriptor() {
+ mirror::ArtMethod* method = GetInterfaceMethodIfProxy();
+ const DexFile* dex_file = method->GetDexFile();
+ const DexFile::MethodId& method_id = dex_file->GetMethodId(method->GetDexMethodIndex());
+ const DexFile::ProtoId& proto_id = dex_file->GetMethodPrototype(method_id);
+ uint16_t return_type_idx = proto_id.return_type_idx_;
+ return dex_file->GetTypeDescriptor(dex_file->GetTypeId(return_type_idx));
+}
+
+inline const char* ArtMethod::GetTypeDescriptorFromTypeIdx(uint16_t type_idx) {
+ mirror::ArtMethod* method = GetInterfaceMethodIfProxy();
+ const DexFile* dex_file = method->GetDexFile();
+ return dex_file->GetTypeDescriptor(dex_file->GetTypeId(type_idx));
+}
+
+inline mirror::ClassLoader* ArtMethod::GetClassLoader() {
+ return GetInterfaceMethodIfProxy()->GetDeclaringClass()->GetClassLoader();
+}
+
+inline mirror::DexCache* ArtMethod::GetDexCache() {
+ return GetInterfaceMethodIfProxy()->GetDeclaringClass()->GetDexCache();
+}
+
+inline ArtMethod* ArtMethod::GetInterfaceMethodIfProxy() {
+ mirror::Class* klass = GetDeclaringClass();
+ if (LIKELY(!klass->IsProxyClass())) {
+ return this;
+ }
+ mirror::ArtMethod* interface_method = GetDexCacheResolvedMethods()->Get(GetDexMethodIndex());
+ DCHECK(interface_method != nullptr);
+ DCHECK_EQ(interface_method,
+ Runtime::Current()->GetClassLinker()->FindMethodForProxy(klass, this));
+ return interface_method;
+}
+
} // namespace mirror
} // namespace art
diff --git a/runtime/mirror/art_method.cc b/runtime/mirror/art_method.cc
index c01fc72..3db4be3 100644
--- a/runtime/mirror/art_method.cc
+++ b/runtime/mirror/art_method.cc
@@ -142,16 +142,16 @@
CHECK_EQ(result,
Runtime::Current()->GetClassLinker()->FindMethodForProxy(GetDeclaringClass(), this));
} else {
- MethodHelper mh(this);
- MethodHelper interface_mh;
+ StackHandleScope<2> hs(Thread::Current());
+ MethodHelper mh(hs.NewHandle(this));
+ MethodHelper interface_mh(hs.NewHandle<mirror::ArtMethod>(nullptr));
IfTable* iftable = GetDeclaringClass()->GetIfTable();
for (size_t i = 0; i < iftable->Count() && result == NULL; i++) {
Class* interface = iftable->GetInterface(i);
for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
- ArtMethod* interface_method = interface->GetVirtualMethod(j);
- interface_mh.ChangeMethod(interface_method);
+ interface_mh.ChangeMethod(interface->GetVirtualMethod(j));
if (mh.HasSameNameAndSignature(&interface_mh)) {
- result = interface_method;
+ result = interface_mh.GetMethod();
break;
}
}
@@ -159,8 +159,10 @@
}
}
#ifndef NDEBUG
- MethodHelper result_mh(result);
- DCHECK(result == NULL || MethodHelper(this).HasSameNameAndSignature(&result_mh));
+ StackHandleScope<2> hs(Thread::Current());
+ MethodHelper result_mh(hs.NewHandle(result));
+ MethodHelper this_mh(hs.NewHandle(this));
+ DCHECK(result == NULL || this_mh.HasSameNameAndSignature(&result_mh));
#endif
return result;
}
@@ -229,10 +231,10 @@
return 0;
}
-uint32_t ArtMethod::FindCatchBlock(Handle<Class> exception_type, uint32_t dex_pc,
- bool* has_no_move_exception) {
- MethodHelper mh(this);
- const DexFile::CodeItem* code_item = mh.GetCodeItem();
+uint32_t ArtMethod::FindCatchBlock(Handle<ArtMethod> h_this, Handle<Class> exception_type,
+ uint32_t dex_pc, bool* has_no_move_exception) {
+ MethodHelper mh(h_this);
+ const DexFile::CodeItem* code_item = h_this->GetCodeItem();
// Set aside the exception while we resolve its type.
Thread* self = Thread::Current();
ThrowLocation throw_location;
@@ -260,7 +262,7 @@
// release its in use context at the end.
delete self->GetLongJumpContext();
LOG(WARNING) << "Unresolved exception class when finding catch block: "
- << DescriptorToDot(mh.GetTypeDescriptorFromTypeIdx(iter_type_idx));
+ << DescriptorToDot(h_this->GetTypeDescriptorFromTypeIdx(iter_type_idx));
} else if (iter_exception_type->IsAssignableFrom(exception_type.Get())) {
found_dex_pc = it.GetHandlerAddress();
break;
@@ -283,7 +285,7 @@
if (kIsDebugBuild) {
self->AssertThreadSuspensionIsAllowable();
CHECK_EQ(kRunnable, self->GetState());
- CHECK_STREQ(MethodHelper(this).GetShorty(), shorty);
+ CHECK_STREQ(GetShorty(), shorty);
}
// Push a transition back into managed code onto the linked list in thread.
diff --git a/runtime/mirror/art_method.h b/runtime/mirror/art_method.h
index f901512..1c21b81 100644
--- a/runtime/mirror/art_method.h
+++ b/runtime/mirror/art_method.h
@@ -88,6 +88,11 @@
return (GetAccessFlags() & kAccConstructor) != 0;
}
+ // Returns true if the method is a class initializer.
+ bool IsClassInitializer() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return IsConstructor() && IsStatic();
+ }
+
// Returns true if the method is static, private, or a constructor.
bool IsDirect() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return IsDirect(GetAccessFlags());
@@ -216,14 +221,14 @@
// Find the method that this method overrides
ArtMethod* FindOverriddenMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void Invoke(Thread* self, uint32_t* args, uint32_t args_size, JValue* result,
- const char* shorty) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void Invoke(Thread* self, uint32_t* args, uint32_t args_size, JValue* result, const char* shorty)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
EntryPointFromInterpreter* GetEntryPointFromInterpreter()
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return GetFieldPtr<EntryPointFromInterpreter*, kVerifyFlags>(
- OFFSET_OF_OBJECT_MEMBER(ArtMethod, entry_point_from_interpreter_));
+ OFFSET_OF_OBJECT_MEMBER(ArtMethod, entry_point_from_interpreter_));
}
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
@@ -281,7 +286,7 @@
*
* NOTE: For Thumb both pc and code are offset by 1 indicating the Thumb state.
*/
- return (code <= pc && pc <= code + GetCodeSize());
+ return code <= pc && pc <= code + GetCodeSize();
}
void AssertPcIsWithinQuickCode(uintptr_t pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -398,8 +403,8 @@
// Find the catch block for the given exception type and dex_pc. When a catch block is found,
// indicates whether the found catch block is responsible for clearing the exception or whether
// a move-exception instruction is present.
- uint32_t FindCatchBlock(Handle<Class> exception_type, uint32_t dex_pc,
- bool* has_no_move_exception)
+ static uint32_t FindCatchBlock(Handle<ArtMethod> h_this, Handle<Class> exception_type,
+ uint32_t dex_pc, bool* has_no_move_exception)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static void SetClass(Class* java_lang_reflect_ArtMethod);
@@ -414,6 +419,30 @@
static void VisitRoots(RootCallback* callback, void* arg)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const DexFile* GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const char* GetDeclaringClassDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const char* GetShorty() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ uint32_t unused_length;
+ return GetShorty(&unused_length);
+ }
+ const char* GetShorty(uint32_t* out_length) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const Signature GetSignature() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const char* GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const DexFile::CodeItem* GetCodeItem() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ bool IsResolvedTypeIdx(uint16_t type_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ int32_t GetLineNumFromDexPC(uint32_t dex_pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const DexFile::ProtoId& GetPrototype() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const DexFile::TypeList* GetParameterTypeList() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const char* GetDeclaringClassSourceFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ uint16_t GetClassDefIndex() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const DexFile::ClassDef& GetClassDef() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const char* GetReturnTypeDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const char* GetTypeDescriptorFromTypeIdx(uint16_t type_idx)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ mirror::ClassLoader* GetClassLoader() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ mirror::DexCache* GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ ArtMethod* GetInterfaceMethodIfProxy() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
protected:
// Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
// The class we are a part of.
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index a409093..7b31a82 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -366,11 +366,9 @@
}
ArtMethod* Class::FindDeclaredDirectMethod(const StringPiece& name, const StringPiece& signature) {
- MethodHelper mh;
for (size_t i = 0; i < NumDirectMethods(); ++i) {
ArtMethod* method = GetDirectMethod(i);
- mh.ChangeMethod(method);
- if (name == mh.GetName() && mh.GetSignature() == signature) {
+ if (name == method->GetName() && method->GetSignature() == signature) {
return method;
}
}
@@ -378,11 +376,9 @@
}
ArtMethod* Class::FindDeclaredDirectMethod(const StringPiece& name, const Signature& signature) {
- MethodHelper mh;
for (size_t i = 0; i < NumDirectMethods(); ++i) {
ArtMethod* method = GetDirectMethod(i);
- mh.ChangeMethod(method);
- if (name == mh.GetName() && signature == mh.GetSignature()) {
+ if (name == method->GetName() && signature == method->GetSignature()) {
return method;
}
}
@@ -432,24 +428,19 @@
}
ArtMethod* Class::FindDeclaredVirtualMethod(const StringPiece& name, const StringPiece& signature) {
- MethodHelper mh;
for (size_t i = 0; i < NumVirtualMethods(); ++i) {
ArtMethod* method = GetVirtualMethod(i);
- mh.ChangeMethod(method);
- if (name == mh.GetName() && mh.GetSignature() == signature) {
+ if (name == method->GetName() && method->GetSignature() == signature) {
return method;
}
}
return NULL;
}
-ArtMethod* Class::FindDeclaredVirtualMethod(const StringPiece& name,
- const Signature& signature) {
- MethodHelper mh;
+ArtMethod* Class::FindDeclaredVirtualMethod(const StringPiece& name, const Signature& signature) {
for (size_t i = 0; i < NumVirtualMethods(); ++i) {
ArtMethod* method = GetVirtualMethod(i);
- mh.ChangeMethod(method);
- if (name == mh.GetName() && signature == mh.GetSignature()) {
+ if (name == method->GetName() && signature == method->GetSignature()) {
return method;
}
}
@@ -501,13 +492,9 @@
ArtMethod* Class::FindClassInitializer() {
for (size_t i = 0; i < NumDirectMethods(); ++i) {
ArtMethod* method = GetDirectMethod(i);
- if (method->IsConstructor() && method->IsStatic()) {
- if (kIsDebugBuild) {
- MethodHelper mh(method);
- CHECK(mh.IsClassInitializer());
- CHECK_STREQ(mh.GetName(), "<clinit>");
- CHECK_STREQ(mh.GetSignature().ToString().c_str(), "()V");
- }
+ if (method->IsClassInitializer()) {
+ DCHECK_STREQ(method->GetName(), "<clinit>");
+ DCHECK_STREQ(method->GetSignature().ToString().c_str(), "()V");
return method;
}
}
diff --git a/runtime/mirror/object_test.cc b/runtime/mirror/object_test.cc
index 18e50ce..f85fb27 100644
--- a/runtime/mirror/object_test.cc
+++ b/runtime/mirror/object_test.cc
@@ -451,7 +451,7 @@
jobject jclass_loader_1 = LoadDex("ProtoCompare");
jobject jclass_loader_2 = LoadDex("ProtoCompare2");
- StackHandleScope<2> hs(soa.Self());
+ StackHandleScope<4> hs(soa.Self());
Handle<ClassLoader> class_loader_1(hs.NewHandle(soa.Decode<ClassLoader*>(jclass_loader_1)));
Handle<ClassLoader> class_loader_2(hs.NewHandle(soa.Decode<ClassLoader*>(jclass_loader_2)));
@@ -461,33 +461,25 @@
ASSERT_TRUE(klass2 != NULL);
ArtMethod* m1_1 = klass1->GetVirtualMethod(0);
- MethodHelper mh(m1_1);
- EXPECT_STREQ(mh.GetName(), "m1");
+ EXPECT_STREQ(m1_1->GetName(), "m1");
ArtMethod* m2_1 = klass1->GetVirtualMethod(1);
- mh.ChangeMethod(m2_1);
- EXPECT_STREQ(mh.GetName(), "m2");
+ EXPECT_STREQ(m2_1->GetName(), "m2");
ArtMethod* m3_1 = klass1->GetVirtualMethod(2);
- mh.ChangeMethod(m3_1);
- EXPECT_STREQ(mh.GetName(), "m3");
+ EXPECT_STREQ(m3_1->GetName(), "m3");
ArtMethod* m4_1 = klass1->GetVirtualMethod(3);
- mh.ChangeMethod(m4_1);
- EXPECT_STREQ(mh.GetName(), "m4");
+ EXPECT_STREQ(m4_1->GetName(), "m4");
ArtMethod* m1_2 = klass2->GetVirtualMethod(0);
- mh.ChangeMethod(m1_2);
- EXPECT_STREQ(mh.GetName(), "m1");
+ EXPECT_STREQ(m1_2->GetName(), "m1");
ArtMethod* m2_2 = klass2->GetVirtualMethod(1);
- mh.ChangeMethod(m2_2);
- EXPECT_STREQ(mh.GetName(), "m2");
+ EXPECT_STREQ(m2_2->GetName(), "m2");
ArtMethod* m3_2 = klass2->GetVirtualMethod(2);
- mh.ChangeMethod(m3_2);
- EXPECT_STREQ(mh.GetName(), "m3");
+ EXPECT_STREQ(m3_2->GetName(), "m3");
ArtMethod* m4_2 = klass2->GetVirtualMethod(3);
- mh.ChangeMethod(m4_2);
- EXPECT_STREQ(mh.GetName(), "m4");
+ EXPECT_STREQ(m4_2->GetName(), "m4");
- mh.ChangeMethod(m1_1);
- MethodHelper mh2(m1_2);
+ MethodHelper mh(hs.NewHandle(m1_1));
+ MethodHelper mh2(hs.NewHandle(m1_2));
EXPECT_TRUE(mh.HasSameNameAndSignature(&mh2));
EXPECT_TRUE(mh2.HasSameNameAndSignature(&mh));
diff --git a/runtime/mirror/throwable.cc b/runtime/mirror/throwable.cc
index 6874fe5..6efc9e2 100644
--- a/runtime/mirror/throwable.cc
+++ b/runtime/mirror/throwable.cc
@@ -85,16 +85,14 @@
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));
- MethodHelper mh;
if (depth == 0) {
result += "(Throwable with empty stack trace)";
} else {
for (int32_t i = 0; i < depth; ++i) {
- ArtMethod* method = down_cast<ArtMethod*>(method_trace->Get(i));
- mh.ChangeMethod(method);
+ mirror::ArtMethod* method = down_cast<ArtMethod*>(method_trace->Get(i));
uint32_t dex_pc = pc_trace->Get(i);
- int32_t line_number = mh.GetLineNumFromDexPC(dex_pc);
- const char* source_file = mh.GetDeclaringClassSourceFile();
+ 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(),
source_file, line_number);
}