summaryrefslogtreecommitdiffstats
path: root/runtime/instrumentation.cc
diff options
context:
space:
mode:
authorJeff Hao <jeffhao@google.com>2014-05-27 18:25:47 -0700
committerJeff Hao <jeffhao@google.com>2014-05-27 18:25:47 -0700
commita15a81b2bd6d08d131e0726ddb622d940ed3c6da (patch)
tree5cff81681ceae0efa521582498af88bf4c0d74ee /runtime/instrumentation.cc
parent33a60e47278d09acfa44d92ad85b1902b57a6b5b (diff)
downloadart-a15a81b2bd6d08d131e0726ddb622d940ed3c6da.zip
art-a15a81b2bd6d08d131e0726ddb622d940ed3c6da.tar.gz
art-a15a81b2bd6d08d131e0726ddb622d940ed3c6da.tar.bz2
Fix method tracing's handling of shadow frames on startup.
Bug: 15142926 Change-Id: I7d7896ec3f62f46a43578f536292db6e219d83f0
Diffstat (limited to 'runtime/instrumentation.cc')
-rw-r--r--runtime/instrumentation.cc30
1 files changed, 17 insertions, 13 deletions
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index 2dbcc80..194cb18 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -180,13 +180,6 @@ static void InstrumentationInstallStack(Thread* thread, void* arg)
virtual bool VisitFrame() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
mirror::ArtMethod* m = GetMethod();
- if (GetCurrentQuickFrame() == NULL) {
- if (kVerboseInstrumentation) {
- LOG(INFO) << " Ignoring a shadow frame. Frame " << GetFrameId()
- << " Method=" << PrettyMethod(m);
- }
- return true; // Ignore shadow frames.
- }
if (m == NULL) {
if (kVerboseInstrumentation) {
LOG(INFO) << " Skipping upcall. Frame " << GetFrameId();
@@ -204,6 +197,14 @@ static void InstrumentationInstallStack(Thread* thread, void* arg)
if (kVerboseInstrumentation) {
LOG(INFO) << " Installing exit stub in " << DescribeLocation();
}
+ if (GetCurrentQuickFrame() == NULL) {
+ InstrumentationStackFrame instrumentation_frame(GetThisObject(), m, 0, GetFrameId(), false);
+ if (kVerboseInstrumentation) {
+ LOG(INFO) << "Pushing shadow frame " << instrumentation_frame.Dump();
+ }
+ shadow_stack_.push_back(instrumentation_frame);
+ return true; // Continue.
+ }
uintptr_t return_pc = GetReturnPc();
if (return_pc == instrumentation_exit_pc_) {
// We've reached a frame which has already been installed with instrumentation exit stub.
@@ -238,6 +239,7 @@ static void InstrumentationInstallStack(Thread* thread, void* arg)
return true; // Continue.
}
std::deque<InstrumentationStackFrame>* const instrumentation_stack_;
+ std::vector<InstrumentationStackFrame> shadow_stack_;
const size_t existing_instrumentation_frames_count_;
std::vector<uint32_t> dex_pcs_;
const uintptr_t instrumentation_exit_pc_;
@@ -261,14 +263,16 @@ static void InstrumentationInstallStack(Thread* thread, void* arg)
if (instrumentation->ShouldNotifyMethodEnterExitEvents()) {
// Create method enter events for all methods currently on the thread's stack. We only do this
// if no debugger is attached to prevent from posting events twice.
- typedef std::deque<InstrumentationStackFrame>::const_reverse_iterator It;
- for (It it = thread->GetInstrumentationStack()->rbegin(),
- end = thread->GetInstrumentationStack()->rend(); it != end; ++it) {
- mirror::Object* this_object = (*it).this_object_;
- mirror::ArtMethod* method = (*it).method_;
+ auto ssi = visitor.shadow_stack_.rbegin();
+ for (auto isi = thread->GetInstrumentationStack()->rbegin(),
+ end = thread->GetInstrumentationStack()->rend(); isi != end; ++isi) {
+ while (ssi != visitor.shadow_stack_.rend() && (*ssi).frame_id_ < (*isi).frame_id_) {
+ instrumentation->MethodEnterEvent(thread, (*ssi).this_object_, (*ssi).method_, 0);
+ ++ssi;
+ }
uint32_t dex_pc = visitor.dex_pcs_.back();
visitor.dex_pcs_.pop_back();
- instrumentation->MethodEnterEvent(thread, this_object, method, dex_pc);
+ instrumentation->MethodEnterEvent(thread, (*isi).this_object_, (*isi).method_, dex_pc);
}
}
thread->VerifyStack();