Fix for implicit null test for oat.
This change also cleans up the notion of the callee save method with a
"IsPhony" call. Stack visitors check whether the frame they are on has a
legitimate method with "HasMethod".
Change-Id: I8ac0fdd595c1e764fdc22cfa9c6a394595f7e141
diff --git a/src/thread.cc b/src/thread.cc
index 153f20f..737faff 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -382,6 +382,10 @@
(*sp_)->GetClass()->GetDescriptor()->Equals("Ljava/lang/reflect/Method;"));
}
+bool Frame::HasMethod() const {
+ return GetMethod() != NULL && (!GetMethod()->IsPhony());
+}
+
uintptr_t Frame::GetReturnPC() const {
byte* pc_addr = reinterpret_cast<byte*>(sp_) +
GetMethod()->GetReturnPcOffsetInBytes();
@@ -693,6 +697,9 @@
}
void VisitFrame(const Frame& frame, uintptr_t pc) {
+ if (!frame.HasMethod()) {
+ return;
+ }
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Method* m = frame.GetMethod();
@@ -1053,8 +1060,10 @@
virtual void VisitFrame(const Frame& frame, uintptr_t pc) {
// We want to skip frames up to and including the exception's constructor.
+ // Note we also skip the frame if it doesn't have a method (namely the callee
+ // save frame)
DCHECK(gThrowable != NULL);
- if (skipping_ && !gThrowable->IsAssignableFrom(frame.GetMethod()->GetDeclaringClass())) {
+ if (skipping_ && frame.HasMethod() && !gThrowable->IsAssignableFrom(frame.GetMethod()->GetDeclaringClass())) {
skipping_ = false;
}
if (!skipping_) {
@@ -1307,17 +1316,17 @@
return;
}
uint32_t dex_pc = DexFile::kDexNoIndex;
- if (pc > 0) {
- if (method->IsNative()) {
- native_method_count_++;
- } else {
- // Move the PC back 2 bytes as a call will frequently terminate the
- // decoding of a particular instruction and we want to make sure we
- // get the Dex PC of the instruction with the call and not the
- // instruction following.
- pc -= 2;
- dex_pc = method->ToDexPC(pc);
- }
+ if (method->IsPhony()) {
+ // ignore callee save method
+ } else if (method->IsNative()) {
+ native_method_count_++;
+ } else {
+ // Move the PC back 2 bytes as a call will frequently terminate the
+ // decoding of a particular instruction and we want to make sure we
+ // get the Dex PC of the instruction with the call and not the
+ // instruction following.
+ pc -= 2;
+ dex_pc = method->ToDexPC(pc);
}
if (dex_pc != DexFile::kDexNoIndex) {
uint32_t found_dex_pc = method->FindCatchBlock(to_find_, dex_pc);