Support for deoptimization needed for debugging.
The deoptimization code is untested, and some sanity checks in the
instrumentation are disabled because they need debugging.
Change-Id: I1b60a65a60bddc9b107ad4659da097b55ce901c3
diff --git a/src/stack.cc b/src/stack.cc
index ed44df9..e962dec 100644
--- a/src/stack.cc
+++ b/src/stack.cc
@@ -142,10 +142,11 @@
*reinterpret_cast<uintptr_t*>(pc_addr) = new_ret_pc;
}
-size_t StackVisitor::ComputeNumFrames() const {
+size_t StackVisitor::ComputeNumFrames(const ManagedStack* stack,
+ const std::deque<InstrumentationStackFrame>* instr_stack) {
struct NumFramesVisitor : public StackVisitor {
explicit NumFramesVisitor(const ManagedStack* stack,
- const std::vector<InstrumentationStackFrame>* instrumentation_stack)
+ const std::deque<InstrumentationStackFrame>* instrumentation_stack)
: StackVisitor(stack, instrumentation_stack, NULL), frames(0) {}
virtual bool VisitFrame() {
@@ -155,15 +156,35 @@
size_t frames;
};
-
- NumFramesVisitor visitor(stack_start_, instrumentation_stack_);
+ UNUSED(instr_stack); // We don't use the instrumentation stack as we don't require dex pcs...
+ NumFramesVisitor visitor(stack, NULL);
visitor.WalkStack(true);
return visitor.frames;
}
+void StackVisitor::DescribeStack(const ManagedStack* stack,
+ const std::deque<InstrumentationStackFrame>* instr_stack) {
+ struct DescribeStackVisitor : public StackVisitor {
+ explicit DescribeStackVisitor(const ManagedStack* stack,
+ const std::deque<InstrumentationStackFrame>* instrumentation_stack)
+ : StackVisitor(stack, instrumentation_stack, NULL) {}
+
+ virtual bool VisitFrame() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ LOG(INFO) << "Frame Id=" << GetFrameId() << " " << DescribeLocation();
+ return true;
+ }
+ };
+ DescribeStackVisitor visitor(stack, instr_stack);
+ visitor.WalkStack(true);
+}
+
std::string StackVisitor::DescribeLocation() const {
std::string result("Visiting method '");
- result += PrettyMethod(GetMethod());
+ AbstractMethod* m = GetMethod();
+ if (m == NULL) {
+ return "upcall";
+ }
+ result += PrettyMethod(m);
result += StringPrintf("' at dex PC 0x%04zx", GetDexPc());
if (!IsShadowFrame()) {
result += StringPrintf(" (native PC %p)", reinterpret_cast<void*>(GetCurrentQuickFramePc()));
@@ -189,7 +210,7 @@
}
void StackVisitor::WalkStack(bool include_transitions) {
- bool method_tracing_active = Runtime::Current()->IsMethodTracingActive();
+ bool method_tracing_active = instrumentation_stack_ != NULL;
uint32_t instrumentation_stack_depth = 0;
for (const ManagedStack* current_fragment = stack_start_; current_fragment != NULL;
current_fragment = current_fragment->GetLink()) {
@@ -218,7 +239,7 @@
// While profiling, the return pc is restored from the side stack, except when walking
// the stack for an exception where the side stack will be unwound in VisitFrame.
// TODO: stop using include_transitions as a proxy for is this the catch block visitor.
- if (IsInstrumentationExitPc(return_pc) && !include_transitions) {
+ if (GetInstrumentationExitPc() == return_pc && !include_transitions) {
// TODO: unify trace and managed stack.
InstrumentationStackFrame instrumentation_frame = GetInstrumentationStackFrame(instrumentation_stack_depth);
instrumentation_stack_depth++;