diff options
Diffstat (limited to 'runtime/debugger.cc')
| -rw-r--r-- | runtime/debugger.cc | 79 |
1 files changed, 42 insertions, 37 deletions
diff --git a/runtime/debugger.cc b/runtime/debugger.cc index 12bdb32fec..b59511214d 100644 --- a/runtime/debugger.cc +++ b/runtime/debugger.cc @@ -18,7 +18,9 @@ #include <sys/uio.h> +#include <memory> #include <set> +#include <vector> #include "android-base/stringprintf.h" @@ -26,6 +28,7 @@ #include "art_field-inl.h" #include "art_method-inl.h" #include "base/enums.h" +#include "base/strlcpy.h" #include "base/time_utils.h" #include "class_linker.h" #include "class_linker-inl.h" @@ -77,25 +80,10 @@ static uint16_t CappedAllocRecordCount(size_t alloc_record_count) { return alloc_record_count; } -// Takes a method and returns a 'canonical' one if the method is default (and therefore potentially -// copied from some other class). This ensures that the debugger does not get confused as to which -// method we are in. -static ArtMethod* GetCanonicalMethod(ArtMethod* m) - REQUIRES_SHARED(Locks::mutator_lock_) { - if (LIKELY(!m->IsDefault())) { - return m; - } else { - mirror::Class* declaring_class = m->GetDeclaringClass(); - return declaring_class->FindDeclaredVirtualMethod(declaring_class->GetDexCache(), - m->GetDexMethodIndex(), - kRuntimePointerSize); - } -} - class Breakpoint : public ValueObject { public: Breakpoint(ArtMethod* method, uint32_t dex_pc, DeoptimizationRequest::Kind deoptimization_kind) - : method_(GetCanonicalMethod(method)), + : method_(method->GetCanonicalMethod(kRuntimePointerSize)), dex_pc_(dex_pc), deoptimization_kind_(deoptimization_kind) { CHECK(deoptimization_kind_ == DeoptimizationRequest::kNothing || @@ -125,7 +113,7 @@ class Breakpoint : public ValueObject { // Returns true if the method of this breakpoint and the passed in method should be considered the // same. That is, they are either the same method or they are copied from the same method. bool IsInMethod(ArtMethod* m) const REQUIRES_SHARED(Locks::mutator_lock_) { - return method_ == GetCanonicalMethod(m); + return method_ == m->GetCanonicalMethod(kRuntimePointerSize); } private: @@ -1367,7 +1355,8 @@ JDWP::FieldId Dbg::ToFieldId(const ArtField* f) { static JDWP::MethodId ToMethodId(ArtMethod* m) REQUIRES_SHARED(Locks::mutator_lock_) { - return static_cast<JDWP::MethodId>(reinterpret_cast<uintptr_t>(GetCanonicalMethod(m))); + return static_cast<JDWP::MethodId>( + reinterpret_cast<uintptr_t>(m->GetCanonicalMethod(kRuntimePointerSize))); } static ArtField* FromFieldId(JDWP::FieldId fid) @@ -2460,7 +2449,7 @@ JDWP::JdwpError Dbg::SuspendThread(JDWP::ObjectId thread_id, bool request_suspen ThreadList* thread_list = Runtime::Current()->GetThreadList(); Thread* thread = thread_list->SuspendThreadByPeer(peer.get(), request_suspension, - /* debug_suspension */ true, + SuspendReason::kForDebugger, &timed_out); if (thread != nullptr) { return JDWP::ERR_NONE; @@ -2491,7 +2480,7 @@ void Dbg::ResumeThread(JDWP::ObjectId thread_id) { needs_resume = thread->GetDebugSuspendCount() > 0; } if (needs_resume) { - Runtime::Current()->GetThreadList()->Resume(thread, true); + Runtime::Current()->GetThreadList()->Resume(thread, SuspendReason::kForDebugger); } } @@ -2887,7 +2876,7 @@ static void SetEventLocation(JDWP::EventLocation* location, ArtMethod* m, uint32 if (m == nullptr) { memset(location, 0, sizeof(*location)); } else { - location->method = GetCanonicalMethod(m); + location->method = m->GetCanonicalMethod(kRuntimePointerSize); location->dex_pc = (m->IsNative() || m->IsProxyMethod()) ? static_cast<uint32_t>(-1) : dex_pc; } } @@ -3708,7 +3697,7 @@ class ScopedDebuggerThreadSuspension { ThreadList* const thread_list = Runtime::Current()->GetThreadList(); suspended_thread = thread_list->SuspendThreadByPeer(thread_peer, /* request_suspension */ true, - /* debug_suspension */ true, + SuspendReason::kForDebugger, &timed_out); } if (suspended_thread == nullptr) { @@ -3732,7 +3721,7 @@ class ScopedDebuggerThreadSuspension { ~ScopedDebuggerThreadSuspension() { if (other_suspend_) { - Runtime::Current()->GetThreadList()->Resume(thread_, true); + Runtime::Current()->GetThreadList()->Resume(thread_, SuspendReason::kForDebugger); } } @@ -4054,7 +4043,7 @@ JDWP::JdwpError Dbg::PrepareInvokeMethod(uint32_t request_id, JDWP::ObjectId thr thread_list->UndoDebuggerSuspensions(); } else { VLOG(jdwp) << " Resuming event thread only"; - thread_list->Resume(targetThread, true); + thread_list->Resume(targetThread, SuspendReason::kForDebugger); } return JDWP::ERR_NONE; @@ -4940,11 +4929,20 @@ class StringTable { StringTable() { } - void Add(const std::string& str) { - table_.insert(str); - } + void Add(const char* str, bool copy_string) { + if (UNLIKELY(copy_string)) { + // Check whether it's already there. + if (table_.find(str) != table_.end()) { + return; + } - void Add(const char* str) { + // Make a copy. + size_t str_len = strlen(str); + char* copy = new char[str_len + 1]; + strlcpy(copy, str, str_len + 1); + string_backup_.emplace_back(copy); + str = copy; + } table_.insert(str); } @@ -4961,17 +4959,23 @@ class StringTable { } void WriteTo(std::vector<uint8_t>& bytes) const { - for (const std::string& str : table_) { - const char* s = str.c_str(); - size_t s_len = CountModifiedUtf8Chars(s); + for (const char* str : table_) { + size_t s_len = CountModifiedUtf8Chars(str); std::unique_ptr<uint16_t[]> s_utf16(new uint16_t[s_len]); - ConvertModifiedUtf8ToUtf16(s_utf16.get(), s); + ConvertModifiedUtf8ToUtf16(s_utf16.get(), str); JDWP::AppendUtf16BE(bytes, s_utf16.get(), s_len); } } private: - std::set<std::string> table_; + struct ConstCharStarComparator { + bool operator()(const char *s1, const char *s2) const { + return strcmp(s1, s2) < 0; + } + }; + + std::set<const char*, ConstCharStarComparator> table_; + std::vector<std::unique_ptr<char[]>> string_backup_; DISALLOW_COPY_AND_ASSIGN(StringTable); }; @@ -5058,12 +5062,13 @@ jbyteArray Dbg::GetRecentAllocations() { count > 0 && it != end; count--, it++) { const gc::AllocRecord* record = &it->second; std::string temp; - class_names.Add(record->GetClassDescriptor(&temp)); + const char* class_descr = record->GetClassDescriptor(&temp); + class_names.Add(class_descr, !temp.empty()); for (size_t i = 0, depth = record->GetDepth(); i < depth; i++) { ArtMethod* m = record->StackElement(i).GetMethod(); - class_names.Add(m->GetDeclaringClassDescriptor()); - method_names.Add(m->GetName()); - filenames.Add(GetMethodSourceFile(m)); + class_names.Add(m->GetDeclaringClassDescriptor(), false); + method_names.Add(m->GetName(), false); + filenames.Add(GetMethodSourceFile(m), false); } } |