diff options
author | 2019-09-10 16:46:48 -0700 | |
---|---|---|
committer | 2019-09-11 17:17:22 +0000 | |
commit | 0054aa59c50374751cc65e8de31a1d813912e67d (patch) | |
tree | e09f2fdc04fdfda86b2c7ecb3b980a3687323597 | |
parent | 4945b29e6ea494fffc924f5940601af58d2b28ab (diff) |
Have JavaFrameRootInfo give more info about provenance of root.
It can be useful to differentiate between java frame roots being the
methods declaring class, from a proxy method, being unknown due to
an imprecise walk or being indeterminable. This passes that
information with the Vreg.
Test: ./test.py --host
Bug: 134162467
Change-Id: I74842d3eeedee5c836511e046652502a53de0f7e
-rw-r--r-- | openjdkjvmti/ti_heap.cc | 4 | ||||
-rw-r--r-- | runtime/java_frame_root_info.cc | 13 | ||||
-rw-r--r-- | runtime/java_frame_root_info.h | 15 | ||||
-rw-r--r-- | runtime/thread.cc | 12 |
4 files changed, 36 insertions, 8 deletions
diff --git a/openjdkjvmti/ti_heap.cc b/openjdkjvmti/ti_heap.cc index 0c06ae1169..81d1fc778f 100644 --- a/openjdkjvmti/ti_heap.cc +++ b/openjdkjvmti/ti_heap.cc @@ -1039,7 +1039,9 @@ class FollowReferencesHelper final { } auto& java_info = static_cast<const art::JavaFrameRootInfo&>(info); - ref_info->stack_local.slot = static_cast<jint>(java_info.GetVReg()); + size_t vreg = java_info.GetVReg(); + ref_info->stack_local.slot = static_cast<jint>( + vreg <= art::JavaFrameRootInfo::kMaxVReg ? vreg : -1); const art::StackVisitor* visitor = java_info.GetVisitor(); ref_info->stack_local.location = static_cast<jlocation>(visitor->GetDexPc(/* abort_on_failure= */ false)); diff --git a/runtime/java_frame_root_info.cc b/runtime/java_frame_root_info.cc index dd3be5d415..9a0f184a83 100644 --- a/runtime/java_frame_root_info.cc +++ b/runtime/java_frame_root_info.cc @@ -24,7 +24,18 @@ void JavaFrameRootInfo::Describe(std::ostream& os) const { const StackVisitor* visitor = stack_visitor_; CHECK(visitor != nullptr); os << "Type=" << GetType() << " thread_id=" << GetThreadId() << " location=" << - visitor->DescribeLocation() << " vreg=" << vreg_; + visitor->DescribeLocation() << " vreg="; + if (vreg_ == JavaFrameRootInfo::kUnknownVreg) { + os << "Unknown"; + } else if (vreg_ == JavaFrameRootInfo::kImpreciseVreg) { + os << "imprecise"; + } else if (vreg_ == JavaFrameRootInfo::kProxyReferenceArgument) { + os << "Proxy reference argument"; + } else if (vreg_ == JavaFrameRootInfo::kMethodDeclaringClass) { + os << "method declaring class"; + } else { + os << vreg_; + } } } // namespace art diff --git a/runtime/java_frame_root_info.h b/runtime/java_frame_root_info.h index 8141ea24fd..c21eee1b32 100644 --- a/runtime/java_frame_root_info.h +++ b/runtime/java_frame_root_info.h @@ -18,6 +18,7 @@ #define ART_RUNTIME_JAVA_FRAME_ROOT_INFO_H_ #include <iosfwd> +#include <limits> #include "base/locks.h" #include "base/macros.h" @@ -29,6 +30,20 @@ class StackVisitor; class JavaFrameRootInfo final : public RootInfo { public: + static_assert(std::numeric_limits<size_t>::max() > std::numeric_limits<uint16_t>::max(), + "No extra space in vreg to store meta-data"); + // Unable to determine what register number the root is from. + static constexpr size_t kUnknownVreg = -1; + // The register number for the root might be determinable but we did not attempt to find that + // information. + static constexpr size_t kImpreciseVreg = -2; + // The root is from the declaring class of the current method. + static constexpr size_t kMethodDeclaringClass = -3; + // The root is from the argument to a Proxy invoke. + static constexpr size_t kProxyReferenceArgument = -4; + // The maximum precise vreg number + static constexpr size_t kMaxVReg = std::numeric_limits<uint16_t>::max(); + JavaFrameRootInfo(uint32_t thread_id, const StackVisitor* stack_visitor, size_t vreg) : RootInfo(kRootJavaFrame, thread_id), stack_visitor_(stack_visitor), vreg_(vreg) { } diff --git a/runtime/thread.cc b/runtime/thread.cc index 7adcb11c99..088f997855 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -3757,7 +3757,7 @@ class ReferenceMapVisitor : public StackVisitor { } } mirror::Object* new_ref = klass.Ptr(); - visitor_(&new_ref, /* vreg= */ -1, this); + visitor_(&new_ref, /* vreg= */ JavaFrameRootInfo::kMethodDeclaringClass, this); if (new_ref != klass) { method->CASDeclaringClass(klass.Ptr(), new_ref->AsClass()); } @@ -3830,7 +3830,7 @@ class ReferenceMapVisitor : public StackVisitor { mirror::Object* ref = ref_addr->AsMirrorPtr(); if (ref != nullptr) { mirror::Object* new_ref = ref; - visitor_(&new_ref, /* vreg= */ -1, this); + visitor_(&new_ref, /* vreg= */ JavaFrameRootInfo::kProxyReferenceArgument, this); if (ref != new_ref) { ref_addr->Assign(new_ref); } @@ -3861,7 +3861,7 @@ class ReferenceMapVisitor : public StackVisitor { size_t stack_index ATTRIBUTE_UNUSED, const StackVisitor* stack_visitor) REQUIRES_SHARED(Locks::mutator_lock_) { - visitor(ref, -1, stack_visitor); + visitor(ref, JavaFrameRootInfo::kImpreciseVreg, stack_visitor); } ALWAYS_INLINE @@ -3869,7 +3869,7 @@ class ReferenceMapVisitor : public StackVisitor { size_t register_index ATTRIBUTE_UNUSED, const StackVisitor* stack_visitor) REQUIRES_SHARED(Locks::mutator_lock_) { - visitor(ref, -1, stack_visitor); + visitor(ref, JavaFrameRootInfo::kImpreciseVreg, stack_visitor); } RootVisitor& visitor; @@ -3907,8 +3907,8 @@ class ReferenceMapVisitor : public StackVisitor { } if (!found) { - // If nothing found, report with -1. - visitor(ref, -1, stack_visitor); + // If nothing found, report with unknown. + visitor(ref, JavaFrameRootInfo::kUnknownVreg, stack_visitor); } } |