Remove Frame, merge shadow and quick representations.
Change-Id: I5ae03a5e52111792d2df7e83cbd89ab25777844b
diff --git a/src/debugger.cc b/src/debugger.cc
index 604560e..e3c30f8 100644
--- a/src/debugger.cc
+++ b/src/debugger.cc
@@ -96,10 +96,10 @@
struct AllocRecordStackTraceElement {
Method* method;
- uintptr_t raw_pc;
+ uint32_t dex_pc;
int32_t LineNumber() const {
- return MethodHelper(method).GetLineNumFromNativePC(raw_pc);
+ return MethodHelper(method).GetLineNumFromDexPC(dex_pc);
}
};
@@ -947,7 +947,7 @@
#endif
}
-static void SetLocation(JDWP::JdwpLocation& location, Method* m, uintptr_t native_pc) {
+static void SetLocation(JDWP::JdwpLocation& location, Method* m, uint32_t dex_pc) {
if (m == NULL) {
memset(&location, 0, sizeof(location));
} else {
@@ -955,7 +955,7 @@
location.type_tag = c->IsInterface() ? JDWP::TT_INTERFACE : JDWP::TT_CLASS;
location.class_id = gRegistry->Add(c);
location.method_id = ToMethodId(m);
- location.dex_pc = m->IsNative() ? -1 : m->ToDexPC(native_pc);
+ location.dex_pc = dex_pc;
}
}
@@ -1467,18 +1467,21 @@
}
static int GetStackDepth(Thread* thread) {
- struct CountStackDepthVisitor : public Thread::StackVisitor {
- CountStackDepthVisitor() : depth(0) {}
- bool VisitFrame(const Frame& f, uintptr_t) {
- if (f.HasMethod()) {
+ struct CountStackDepthVisitor : public StackVisitor {
+ CountStackDepthVisitor(const ManagedStack* stack,
+ const std::vector<TraceStackFrame>* trace_stack) :
+ StackVisitor(stack, trace_stack), depth(0) {}
+
+ bool VisitFrame() {
+ if (!GetMethod()->IsRuntimeMethod()) {
++depth;
}
return true;
}
size_t depth;
};
- CountStackDepthVisitor visitor;
- thread->WalkStack(&visitor);
+ CountStackDepthVisitor visitor(thread->GetManagedStack(), thread->GetTraceStack());
+ visitor.WalkStack();
return visitor.depth;
}
@@ -1487,32 +1490,37 @@
return GetStackDepth(DecodeThread(threadId));
}
-void Dbg::GetThreadFrame(JDWP::ObjectId threadId, int desired_frame_number, JDWP::FrameId* pFrameId, JDWP::JdwpLocation* pLoc) {
+void Dbg::GetThreadFrame(JDWP::ObjectId threadId, int desired_frame_number, JDWP::FrameId* pFrameId,
+ JDWP::JdwpLocation* pLoc) {
ScopedThreadListLock thread_list_lock;
- struct GetFrameVisitor : public Thread::StackVisitor {
- GetFrameVisitor(int desired_frame_number, JDWP::FrameId* pFrameId, JDWP::JdwpLocation* pLoc)
- : depth(0), desired_frame_number(desired_frame_number), pFrameId(pFrameId), pLoc(pLoc) {
+ struct GetFrameVisitor : public StackVisitor {
+ GetFrameVisitor(const ManagedStack* stack, const std::vector<TraceStackFrame>* trace_stack,
+ int desired_frame_number, JDWP::FrameId* pFrameId, JDWP::JdwpLocation* pLoc) :
+ StackVisitor(stack, trace_stack), depth(0),
+ desired_frame_number(desired_frame_number), pFrameId(pFrameId), pLoc(pLoc) {
}
- bool VisitFrame(const Frame& f, uintptr_t pc) {
- if (!f.HasMethod()) {
+
+ bool VisitFrame() {
+ if (GetMethod()->IsRuntimeMethod()) {
return true; // The debugger can't do anything useful with a frame that has no Method*.
}
if (depth == desired_frame_number) {
- *pFrameId = reinterpret_cast<JDWP::FrameId>(f.GetSP());
- SetLocation(*pLoc, f.GetMethod(), pc);
+ *pFrameId = GetFrameId();
+ SetLocation(*pLoc, GetMethod(), GetDexPc());
return false;
}
++depth;
return true;
}
int depth;
- int desired_frame_number;
- JDWP::FrameId* pFrameId;
- JDWP::JdwpLocation* pLoc;
+ const int desired_frame_number;
+ JDWP::FrameId* const pFrameId;
+ JDWP::JdwpLocation* const pLoc;
};
- GetFrameVisitor visitor(desired_frame_number, pFrameId, pLoc);
- visitor.desired_frame_number = desired_frame_number;
- DecodeThread(threadId)->WalkStack(&visitor);
+ Thread* thread = DecodeThread(threadId);
+ GetFrameVisitor visitor(thread->GetManagedStack(), thread->GetTraceStack(), desired_frame_number,
+ pFrameId, pLoc);
+ visitor.WalkStack();
}
JDWP::ObjectId Dbg::GetThreadSelfId() {
@@ -1556,180 +1564,252 @@
Runtime::Current()->GetThreadList()->SuspendSelfForDebugger();
}
-static Object* GetThis(Frame& f) {
- Method* m = f.GetMethod();
- Object* o = NULL;
- if (!m->IsNative() && !m->IsStatic()) {
- uint16_t reg = DemangleSlot(0, m);
- o = reinterpret_cast<Object*>(f.GetVReg(m, reg));
+struct GetThisVisitor : public StackVisitor {
+ GetThisVisitor(const ManagedStack* stack, const std::vector<TraceStackFrame>* trace_stack,
+ Context* context, JDWP::FrameId frameId) :
+ StackVisitor(stack, trace_stack, context), thisObject_(NULL), frameId_(frameId) {}
+
+
+ virtual bool VisitFrame() {
+ if (frameId_ != GetFrameId()) {
+ return true; // continue
+ }
+ Method* m = GetMethod();
+ if (m->IsNative() || m->IsStatic()) {
+ thisObject_ = NULL;
+ } else {
+ uint16_t reg = DemangleSlot(0, m);
+ thisObject_ = reinterpret_cast<Object*>(GetVReg(m, reg));
+ }
+ return false;
}
- return o;
+
+ Object* thisObject_;
+ JDWP::FrameId frameId_;
+};
+
+static Object* GetThis(Method** quickFrame) {
+ struct FrameIdVisitor : public StackVisitor {
+ FrameIdVisitor(const ManagedStack* stack, const std::vector<TraceStackFrame>* trace_stack,
+ Method** m) : StackVisitor(stack, trace_stack),
+ quick_frame_to_find_(m) , frame_id_(0) {}
+
+ virtual bool VisitFrame() {
+ if (quick_frame_to_find_ != GetCurrentQuickFrame()) {
+ return true; // Continue.
+ }
+ frame_id_ = GetFrameId();
+ return false; // Stop.
+ }
+
+ Method** const quick_frame_to_find_;
+ JDWP::FrameId frame_id_;
+ };
+
+ Method* m = *quickFrame;
+ if (m->IsNative() || m->IsStatic()) {
+ return NULL;
+ }
+ Thread* self = Thread::Current();
+ const ManagedStack* stack = self->GetManagedStack();
+ const std::vector<TraceStackFrame>* trace_stack = self->GetTraceStack();
+ FrameIdVisitor frameIdVisitor(stack, trace_stack, quickFrame);
+ frameIdVisitor.WalkStack();
+ UniquePtr<Context> context(Context::Create());
+ GetThisVisitor getThisVisitor(stack, trace_stack, context.get(), frameIdVisitor.frame_id_);
+ getThisVisitor.WalkStack();
+ return getThisVisitor.thisObject_;
}
void Dbg::GetThisObject(JDWP::FrameId frameId, JDWP::ObjectId* pThisId) {
- Method** sp = reinterpret_cast<Method**>(frameId);
- Frame f(sp);
- Object* o = GetThis(f);
- *pThisId = gRegistry->Add(o);
+ UniquePtr<Context> context(Context::Create());
+ Thread* self = Thread::Current();
+ GetThisVisitor visitor(self->GetManagedStack(), self->GetTraceStack(), context.get(), frameId);
+ visitor.WalkStack();
+ *pThisId = gRegistry->Add(visitor.thisObject_);
}
-void Dbg::GetLocalValue(JDWP::ObjectId /*threadId*/, JDWP::FrameId frameId, int slot, JDWP::JdwpTag tag, uint8_t* buf, size_t width) {
- Method** sp = reinterpret_cast<Method**>(frameId);
- Frame f(sp);
- Method* m = f.GetMethod();
- uint16_t reg = DemangleSlot(slot, m);
-
-#if defined(ART_USE_LLVM_COMPILER)
- UNIMPLEMENTED(FATAL);
-#else
- const VmapTable vmap_table(m->GetVmapTableRaw());
- uint32_t vmap_offset;
- if (vmap_table.IsInContext(reg, vmap_offset)) {
- UNIMPLEMENTED(FATAL) << "Don't know how to pull locals from callee save frames: " << vmap_offset;
- }
-#endif
-
- // TODO: check that the tag is compatible with the actual type of the slot!
-
- switch (tag) {
- case JDWP::JT_BOOLEAN:
- {
- CHECK_EQ(width, 1U);
- uint32_t intVal = f.GetVReg(m, reg);
- VLOG(jdwp) << "get boolean local " << reg << " = " << intVal;
- JDWP::Set1(buf+1, intVal != 0);
+void Dbg::GetLocalValue(JDWP::ObjectId threadId, JDWP::FrameId frameId, int slot, JDWP::JdwpTag tag, uint8_t* buf, size_t width) {
+ struct GetLocalVisitor : public StackVisitor {
+ GetLocalVisitor(const ManagedStack* stack, const std::vector<TraceStackFrame>* trace_stack,
+ Context* context, JDWP::FrameId frameId, int slot, JDWP::JdwpTag tag,
+ uint8_t* buf, size_t width) :
+ StackVisitor(stack, trace_stack, context), frame_id_(frameId), slot_(slot), tag_(tag),
+ buf_(buf), width_(width) {
}
- break;
- case JDWP::JT_BYTE:
- {
- CHECK_EQ(width, 1U);
- uint32_t intVal = f.GetVReg(m, reg);
- VLOG(jdwp) << "get byte local " << reg << " = " << intVal;
- JDWP::Set1(buf+1, intVal);
- }
- break;
- case JDWP::JT_SHORT:
- case JDWP::JT_CHAR:
- {
- CHECK_EQ(width, 2U);
- uint32_t intVal = f.GetVReg(m, reg);
- VLOG(jdwp) << "get short/char local " << reg << " = " << intVal;
- JDWP::Set2BE(buf+1, intVal);
- }
- break;
- case JDWP::JT_INT:
- case JDWP::JT_FLOAT:
- {
- CHECK_EQ(width, 4U);
- uint32_t intVal = f.GetVReg(m, reg);
- VLOG(jdwp) << "get int/float local " << reg << " = " << intVal;
- JDWP::Set4BE(buf+1, intVal);
- }
- break;
- case JDWP::JT_ARRAY:
- {
- CHECK_EQ(width, sizeof(JDWP::ObjectId));
- Object* o = reinterpret_cast<Object*>(f.GetVReg(m, reg));
- VLOG(jdwp) << "get array local " << reg << " = " << o;
- if (!Runtime::Current()->GetHeap()->IsHeapAddress(o)) {
- LOG(FATAL) << "Register " << reg << " expected to hold array: " << o;
+ bool VisitFrame() {
+ if (GetFrameId() != frame_id_) {
+ return true; // Not our frame, carry on.
}
- JDWP::SetObjectId(buf+1, gRegistry->Add(o));
- }
- break;
- case JDWP::JT_CLASS_LOADER:
- case JDWP::JT_CLASS_OBJECT:
- case JDWP::JT_OBJECT:
- case JDWP::JT_STRING:
- case JDWP::JT_THREAD:
- case JDWP::JT_THREAD_GROUP:
- {
- CHECK_EQ(width, sizeof(JDWP::ObjectId));
- Object* o = reinterpret_cast<Object*>(f.GetVReg(m, reg));
- VLOG(jdwp) << "get object local " << reg << " = " << o;
- if (!Runtime::Current()->GetHeap()->IsHeapAddress(o)) {
- LOG(FATAL) << "Register " << reg << " expected to hold object: " << o;
- }
- tag = TagFromObject(o);
- JDWP::SetObjectId(buf+1, gRegistry->Add(o));
- }
- break;
- case JDWP::JT_DOUBLE:
- case JDWP::JT_LONG:
- {
- CHECK_EQ(width, 8U);
- uint32_t lo = f.GetVReg(m, reg);
- uint64_t hi = f.GetVReg(m, reg + 1);
- uint64_t longVal = (hi << 32) | lo;
- VLOG(jdwp) << "get double/long local " << hi << ":" << lo << " = " << longVal;
- JDWP::Set8BE(buf+1, longVal);
- }
- break;
- default:
- LOG(FATAL) << "Unknown tag " << tag;
- break;
- }
+ // TODO: check that the tag is compatible with the actual type of the slot!
+ Method* m = GetMethod();
+ uint16_t reg = DemangleSlot(slot_, m);
- // Prepend tag, which may have been updated.
- JDWP::Set1(buf, tag);
+ switch (tag_) {
+ case JDWP::JT_BOOLEAN:
+ {
+ CHECK_EQ(width_, 1U);
+ uint32_t intVal = GetVReg(m, reg);
+ VLOG(jdwp) << "get boolean local " << reg << " = " << intVal;
+ JDWP::Set1(buf_+1, intVal != 0);
+ }
+ break;
+ case JDWP::JT_BYTE:
+ {
+ CHECK_EQ(width_, 1U);
+ uint32_t intVal = GetVReg(m, reg);
+ VLOG(jdwp) << "get byte local " << reg << " = " << intVal;
+ JDWP::Set1(buf_+1, intVal);
+ }
+ break;
+ case JDWP::JT_SHORT:
+ case JDWP::JT_CHAR:
+ {
+ CHECK_EQ(width_, 2U);
+ uint32_t intVal = GetVReg(m, reg);
+ VLOG(jdwp) << "get short/char local " << reg << " = " << intVal;
+ JDWP::Set2BE(buf_+1, intVal);
+ }
+ break;
+ case JDWP::JT_INT:
+ case JDWP::JT_FLOAT:
+ {
+ CHECK_EQ(width_, 4U);
+ uint32_t intVal = GetVReg(m, reg);
+ VLOG(jdwp) << "get int/float local " << reg << " = " << intVal;
+ JDWP::Set4BE(buf_+1, intVal);
+ }
+ break;
+ case JDWP::JT_ARRAY:
+ {
+ CHECK_EQ(width_, sizeof(JDWP::ObjectId));
+ Object* o = reinterpret_cast<Object*>(GetVReg(m, reg));
+ VLOG(jdwp) << "get array local " << reg << " = " << o;
+ if (!Runtime::Current()->GetHeap()->IsHeapAddress(o)) {
+ LOG(FATAL) << "Register " << reg << " expected to hold array: " << o;
+ }
+ JDWP::SetObjectId(buf_+1, gRegistry->Add(o));
+ }
+ break;
+ case JDWP::JT_CLASS_LOADER:
+ case JDWP::JT_CLASS_OBJECT:
+ case JDWP::JT_OBJECT:
+ case JDWP::JT_STRING:
+ case JDWP::JT_THREAD:
+ case JDWP::JT_THREAD_GROUP:
+ {
+ CHECK_EQ(width_, sizeof(JDWP::ObjectId));
+ Object* o = reinterpret_cast<Object*>(GetVReg(m, reg));
+ VLOG(jdwp) << "get object local " << reg << " = " << o;
+ if (!Runtime::Current()->GetHeap()->IsHeapAddress(o)) {
+ LOG(FATAL) << "Register " << reg << " expected to hold object: " << o;
+ }
+ tag_ = TagFromObject(o);
+ JDWP::SetObjectId(buf_+1, gRegistry->Add(o));
+ }
+ break;
+ case JDWP::JT_DOUBLE:
+ case JDWP::JT_LONG:
+ {
+ CHECK_EQ(width_, 8U);
+ uint32_t lo = GetVReg(m, reg);
+ uint64_t hi = GetVReg(m, reg + 1);
+ uint64_t longVal = (hi << 32) | lo;
+ VLOG(jdwp) << "get double/long local " << hi << ":" << lo << " = " << longVal;
+ JDWP::Set8BE(buf_+1, longVal);
+ }
+ break;
+ default:
+ LOG(FATAL) << "Unknown tag " << tag_;
+ break;
+ }
+
+ // Prepend tag, which may have been updated.
+ JDWP::Set1(buf_, tag_);
+ return false;
+ }
+
+ const JDWP::FrameId frame_id_;
+ const int slot_;
+ JDWP::JdwpTag tag_;
+ uint8_t* const buf_;
+ const size_t width_;
+ };
+ Thread* thread = DecodeThread(threadId);
+ UniquePtr<Context> context(Context::Create());
+ GetLocalVisitor visitor(thread->GetManagedStack(), thread->GetTraceStack(), context.get(),
+ frameId, slot, tag, buf, width);
+ visitor.WalkStack();
}
-void Dbg::SetLocalValue(JDWP::ObjectId /*threadId*/, JDWP::FrameId frameId, int slot, JDWP::JdwpTag tag, uint64_t value, size_t width) {
- Method** sp = reinterpret_cast<Method**>(frameId);
- Frame f(sp);
- Method* m = f.GetMethod();
- uint16_t reg = DemangleSlot(slot, m);
-
-#if defined(ART_USE_LLVM_COMPILER)
- UNIMPLEMENTED(FATAL);
-#else
- const VmapTable vmap_table(m->GetVmapTableRaw());
- uint32_t vmap_offset;
- if (vmap_table.IsInContext(reg, vmap_offset)) {
- UNIMPLEMENTED(FATAL) << "Don't know how to pull locals from callee save frames: " << vmap_offset;
- }
-#endif
-
- // TODO: check that the tag is compatible with the actual type of the slot!
-
- switch (tag) {
- case JDWP::JT_BOOLEAN:
- case JDWP::JT_BYTE:
- CHECK_EQ(width, 1U);
- f.SetVReg(m, reg, static_cast<uint32_t>(value));
- break;
- case JDWP::JT_SHORT:
- case JDWP::JT_CHAR:
- CHECK_EQ(width, 2U);
- f.SetVReg(m, reg, static_cast<uint32_t>(value));
- break;
- case JDWP::JT_INT:
- case JDWP::JT_FLOAT:
- CHECK_EQ(width, 4U);
- f.SetVReg(m, reg, static_cast<uint32_t>(value));
- break;
- case JDWP::JT_ARRAY:
- case JDWP::JT_OBJECT:
- case JDWP::JT_STRING:
- {
- CHECK_EQ(width, sizeof(JDWP::ObjectId));
- Object* o = gRegistry->Get<Object*>(static_cast<JDWP::ObjectId>(value));
- if (o == kInvalidObject) {
- UNIMPLEMENTED(FATAL) << "return an error code when given an invalid object to store";
- }
- f.SetVReg(m, reg, static_cast<uint32_t>(reinterpret_cast<uintptr_t>(o)));
+void Dbg::SetLocalValue(JDWP::ObjectId threadId, JDWP::FrameId frameId, int slot, JDWP::JdwpTag tag,
+ uint64_t value, size_t width) {
+ struct SetLocalVisitor : public StackVisitor {
+ SetLocalVisitor(const ManagedStack* stack, const std::vector<TraceStackFrame>* trace_stack,
+ JDWP::FrameId frame_id, int slot, JDWP::JdwpTag tag, uint64_t value,
+ size_t width) :
+ StackVisitor(stack, trace_stack), frame_id_(frame_id), slot_(slot), tag_(tag),
+ value_(value), width_(width) {
}
- break;
- case JDWP::JT_DOUBLE:
- case JDWP::JT_LONG:
- CHECK_EQ(width, 8U);
- f.SetVReg(m, reg, static_cast<uint32_t>(value));
- f.SetVReg(m, reg + 1, static_cast<uint32_t>(value >> 32));
- break;
- default:
- LOG(FATAL) << "Unknown tag " << tag;
- break;
- }
+ bool VisitFrame() {
+ if (GetFrameId() != frame_id_) {
+ return true; // Not our frame, carry on.
+ }
+ // TODO: check that the tag is compatible with the actual type of the slot!
+ Method* m = GetMethod();
+ uint16_t reg = DemangleSlot(slot_, m);
+
+ switch (tag_) {
+ case JDWP::JT_BOOLEAN:
+ case JDWP::JT_BYTE:
+ CHECK_EQ(width_, 1U);
+ SetVReg(m, reg, static_cast<uint32_t>(value_));
+ break;
+ case JDWP::JT_SHORT:
+ case JDWP::JT_CHAR:
+ CHECK_EQ(width_, 2U);
+ SetVReg(m, reg, static_cast<uint32_t>(value_));
+ break;
+ case JDWP::JT_INT:
+ case JDWP::JT_FLOAT:
+ CHECK_EQ(width_, 4U);
+ SetVReg(m, reg, static_cast<uint32_t>(value_));
+ break;
+ case JDWP::JT_ARRAY:
+ case JDWP::JT_OBJECT:
+ case JDWP::JT_STRING:
+ {
+ CHECK_EQ(width_, sizeof(JDWP::ObjectId));
+ Object* o = gRegistry->Get<Object*>(static_cast<JDWP::ObjectId>(value_));
+ if (o == kInvalidObject) {
+ UNIMPLEMENTED(FATAL) << "return an error code when given an invalid object to store";
+ }
+ SetVReg(m, reg, static_cast<uint32_t>(reinterpret_cast<uintptr_t>(o)));
+ }
+ break;
+ case JDWP::JT_DOUBLE:
+ case JDWP::JT_LONG:
+ CHECK_EQ(width_, 8U);
+ SetVReg(m, reg, static_cast<uint32_t>(value_));
+ SetVReg(m, reg + 1, static_cast<uint32_t>(value_ >> 32));
+ break;
+ default:
+ LOG(FATAL) << "Unknown tag " << tag_;
+ break;
+ }
+ return false;
+ }
+
+ const JDWP::FrameId frame_id_;
+ const int slot_;
+ const JDWP::JdwpTag tag_;
+ const uint64_t value_;
+ const size_t width_;
+ };
+ Thread* thread = DecodeThread(threadId);
+ SetLocalVisitor visitor(thread->GetManagedStack(), thread->GetTraceStack(), frameId, slot, tag,
+ value, width);
+ visitor.WalkStack();
}
void Dbg::PostLocationEvent(const Method* m, int dex_pc, Object* this_object, int event_flags) {
@@ -1753,19 +1833,20 @@
}
}
-void Dbg::PostException(Method** sp, Method* throwMethod, uintptr_t throwNativePc, Method* catchMethod, uintptr_t catchNativePc, Object* exception) {
+void Dbg::PostException(JDWP::FrameId throwFrameId, Method* throwMethod, uint32_t throwDexPc,
+ Method* catchMethod, uint32_t catchDexPc, Throwable* exception) {
if (!IsDebuggerActive()) {
return;
}
JDWP::JdwpLocation throw_location;
- SetLocation(throw_location, throwMethod, throwNativePc);
+ SetLocation(throw_location, throwMethod, throwDexPc);
JDWP::JdwpLocation catch_location;
- SetLocation(catch_location, catchMethod, catchNativePc);
+ SetLocation(catch_location, catchMethod, catchDexPc);
// We need 'this' for InstanceOnly filters.
JDWP::ObjectId this_id;
- GetThisObject(reinterpret_cast<JDWP::FrameId>(sp), &this_id);
+ GetThisObject(throwFrameId, &this_id);
/*
* Hand the event to the JDWP exception handler. Note we're using the
@@ -1800,15 +1881,13 @@
return;
}
- Frame f(sp);
- f.Next(); // Skip callee save frame.
- Method* m = f.GetMethod();
+ Method* m = self->GetCurrentMethod();
if (dex_pc == -1) {
// We use a pc of -1 to represent method entry, since we might branch back to pc 0 later.
// This means that for this special notification, there can't be anything else interesting
// going on, so we're done already.
- Dbg::PostLocationEvent(m, 0, GetThis(f), kMethodEntry);
+ Dbg::PostLocationEvent(m, 0, GetThis(sp), kMethodEntry);
return;
}
@@ -1899,7 +1978,7 @@
// If there's something interesting going on, see if it matches one
// of the debugger filters.
if (event_flags != 0) {
- Dbg::PostLocationEvent(m, dex_pc, GetThis(f), event_flags);
+ Dbg::PostLocationEvent(m, dex_pc, GetThis(sp), event_flags);
}
}
@@ -1942,32 +2021,34 @@
// is for step-out.
//
- struct SingleStepStackVisitor : public Thread::StackVisitor {
- SingleStepStackVisitor() {
+ struct SingleStepStackVisitor : public StackVisitor {
+ SingleStepStackVisitor(const ManagedStack* stack,
+ const std::vector<TraceStackFrame>* trace_stack) :
+ StackVisitor(stack, trace_stack) {
MutexLock mu(gBreakpointsLock); // Keep GCC happy.
gSingleStepControl.method = NULL;
gSingleStepControl.stack_depth = 0;
}
- bool VisitFrame(const Frame& f, uintptr_t pc) {
+ bool VisitFrame() {
MutexLock mu(gBreakpointsLock); // Keep GCC happy.
- if (f.HasMethod()) {
+ const Method* m = GetMethod();
+ if (!m->IsRuntimeMethod()) {
++gSingleStepControl.stack_depth;
if (gSingleStepControl.method == NULL) {
- const Method* m = f.GetMethod();
const DexCache* dex_cache = m->GetDeclaringClass()->GetDexCache();
gSingleStepControl.method = m;
gSingleStepControl.line_number = -1;
if (dex_cache != NULL) {
const DexFile& dex_file = Runtime::Current()->GetClassLinker()->FindDexFile(dex_cache);
- gSingleStepControl.line_number = dex_file.GetLineNumFromPC(m, m->ToDexPC(pc));
+ gSingleStepControl.line_number = dex_file.GetLineNumFromPC(m, GetDexPc());
}
}
}
return true;
}
};
- SingleStepStackVisitor visitor;
- thread->WalkStack(&visitor);
+ SingleStepStackVisitor visitor(thread->GetManagedStack(), thread->GetTraceStack());
+ visitor.WalkStack();
//
// Find the dex_pc values that correspond to the current line, for line-based single-stepping.
@@ -2835,17 +2916,20 @@
}
}
-struct AllocRecordStackVisitor : public Thread::StackVisitor {
- explicit AllocRecordStackVisitor(AllocRecord* record) : record(record), depth(0) {
+struct AllocRecordStackVisitor : public StackVisitor {
+ AllocRecordStackVisitor(const ManagedStack* stack,
+ const std::vector<TraceStackFrame>* trace_stack, AllocRecord* record) :
+ StackVisitor(stack, trace_stack), record(record), depth(0) {
}
- bool VisitFrame(const Frame& f, uintptr_t pc) {
+ bool VisitFrame() {
if (depth >= kMaxAllocRecordStackDepth) {
return false;
}
- if (f.HasMethod()) {
- record->stack[depth].method = f.GetMethod();
- record->stack[depth].raw_pc = pc;
+ Method* m = GetMethod();
+ if (!m->IsRuntimeMethod()) {
+ record->stack[depth].method = m;
+ record->stack[depth].dex_pc = GetDexPc();
++depth;
}
return true;
@@ -2855,7 +2939,7 @@
// Clear out any unused stack trace elements.
for (; depth < kMaxAllocRecordStackDepth; ++depth) {
record->stack[depth].method = NULL;
- record->stack[depth].raw_pc = 0;
+ record->stack[depth].dex_pc = 0;
}
}
@@ -2884,8 +2968,8 @@
record->thin_lock_id = self->GetThinLockId();
// Fill in the stack trace.
- AllocRecordStackVisitor visitor(record);
- self->WalkStack(&visitor);
+ AllocRecordStackVisitor visitor(self->GetManagedStack(), self->GetTraceStack(), record);
+ visitor.WalkStack();
if (gAllocRecordCount < kNumAllocRecords) {
++gAllocRecordCount;