summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Alex Light <allight@google.com> 2019-09-10 16:46:48 -0700
committer Alex Light <allight@google.com> 2019-09-11 17:17:22 +0000
commit0054aa59c50374751cc65e8de31a1d813912e67d (patch)
treee09f2fdc04fdfda86b2c7ecb3b980a3687323597
parent4945b29e6ea494fffc924f5940601af58d2b28ab (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.cc4
-rw-r--r--runtime/java_frame_root_info.cc13
-rw-r--r--runtime/java_frame_root_info.h15
-rw-r--r--runtime/thread.cc12
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);
}
}