Show ArtMethods in imgdiag
Since ArtMethods were moved out of mirror:: classes imgdiag does not
show information about them. Diff ArtMethods to facilitate finding
dirty memory there.
Bug: 38173645
Test: imgdiag --boot-image=/system/framework/boot.art --image-diff-pid=`pid system_server`
Change-Id: Icd86a9ef14d5177a297026c22c81c080f5c85fc1
diff --git a/runtime/art_method.h b/runtime/art_method.h
index 2d67761..dab3f23 100644
--- a/runtime/art_method.h
+++ b/runtime/art_method.h
@@ -671,6 +671,24 @@
template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier, typename Visitor>
ALWAYS_INLINE void UpdateEntrypoints(const Visitor& visitor, PointerSize pointer_size);
+ // Visit the individual members of an ArtMethod. Used by imgdiag.
+ // As imgdiag does not support mixing instruction sets or pointer sizes (e.g., using imgdiag32
+ // to inspect 64-bit images, etc.), we can go beneath the accessors directly to the class members.
+ template <typename VisitorFunc>
+ void VisitMembers(VisitorFunc& visitor) {
+ DCHECK(IsImagePointerSize(kRuntimePointerSize));
+ visitor(this, &declaring_class_, "declaring_class_");
+ visitor(this, &access_flags_, "access_flags_");
+ visitor(this, &dex_code_item_offset_, "dex_code_item_offset_");
+ visitor(this, &dex_method_index_, "dex_method_index_");
+ visitor(this, &method_index_, "method_index_");
+ visitor(this, &hotness_count_, "hotness_count_");
+ visitor(this, &ptr_sized_fields_.data_, "ptr_sized_fields_.data_");
+ visitor(this,
+ &ptr_sized_fields_.entry_point_from_quick_compiled_code_,
+ "ptr_sized_fields_.entry_point_from_quick_compiled_code_");
+ }
+
protected:
// Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
// The class we are a part of.
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 4161754..835d940 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -8368,6 +8368,10 @@
(quick_generic_jni_trampoline_ == entry_point);
}
+bool ClassLinker::IsJniDlsymLookupStub(const void* entry_point) const {
+ return entry_point == GetJniDlsymLookupStub();
+}
+
const void* ClassLinker::GetRuntimeQuickGenericJniStub() const {
return GetQuickGenericJniStub();
}
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 9727adf..2f92da3 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -500,6 +500,9 @@
// Is the given entry point quick code to run the generic JNI stub?
bool IsQuickGenericJniStub(const void* entry_point) const;
+ // Is the given entry point the JNI dlsym lookup stub?
+ bool IsJniDlsymLookupStub(const void* entry_point) const;
+
const void* GetQuickToInterpreterBridgeTrampoline() const {
return quick_to_interpreter_bridge_trampoline_;
}
diff --git a/runtime/image.cc b/runtime/image.cc
index c8581c1..0236f47 100644
--- a/runtime/image.cc
+++ b/runtime/image.cc
@@ -144,6 +144,19 @@
return os << "size=" << section.Size() << " range=" << section.Offset() << "-" << section.End();
}
+void ImageHeader::VisitObjects(ObjectVisitor* visitor,
+ uint8_t* base,
+ PointerSize pointer_size) const {
+ DCHECK_EQ(pointer_size, GetPointerSize());
+ const ImageSection& objects = GetObjectsSection();
+ static const size_t kStartPos = RoundUp(sizeof(ImageHeader), kObjectAlignment);
+ for (size_t pos = kStartPos; pos < objects.Size(); ) {
+ mirror::Object* object = reinterpret_cast<mirror::Object*>(base + objects.Offset() + pos);
+ visitor->Visit(object);
+ pos += RoundUp(object->SizeOf(), kObjectAlignment);
+ }
+}
+
void ImageHeader::VisitPackedArtFields(ArtFieldVisitor* visitor, uint8_t* base) const {
const ImageSection& fields = GetFieldsSection();
for (size_t pos = 0; pos < fields.Size(); ) {
diff --git a/runtime/image.h b/runtime/image.h
index 2b24087..da04333 100644
--- a/runtime/image.h
+++ b/runtime/image.h
@@ -29,6 +29,13 @@
class ArtField;
class ArtMethod;
+class ObjectVisitor {
+ public:
+ virtual ~ObjectVisitor() {}
+
+ virtual void Visit(mirror::Object* object) = 0;
+};
+
class ArtMethodVisitor {
public:
virtual ~ArtMethodVisitor() {}
@@ -328,6 +335,13 @@
return RoundUp(tables_size, kPageSize);
}
+ // Visit mirror::Objects in the section starting at base.
+ // TODO: Delete base parameter if it is always equal to GetImageBegin.
+ void VisitObjects(ObjectVisitor* visitor,
+ uint8_t* base,
+ PointerSize pointer_size) const
+ REQUIRES_SHARED(Locks::mutator_lock_);
+
// Visit ArtMethods in the section starting at base. Includes runtime methods.
// TODO: Delete base parameter if it is always equal to GetImageBegin.
void VisitPackedArtMethods(ArtMethodVisitor* visitor,