Revert "Revert "Basic structural redefinition support""
This reverts commit 5a2301d897294ff4ee6de71f459dc2566dc3fa1a.
Bug: 134162467
Reason for revert: Relanding as unclear if issue is due to topic.
Change-Id: Ib1d1cf2e9132e30c9649b760ae9ae2d8ceacf843
diff --git a/runtime/art_method.cc b/runtime/art_method.cc
index d8bcb02..646f73d 100644
--- a/runtime/art_method.cc
+++ b/runtime/art_method.cc
@@ -16,12 +16,15 @@
#include "art_method.h"
+#include <algorithm>
#include <cstddef>
#include "android-base/stringprintf.h"
#include "arch/context.h"
#include "art_method-inl.h"
+#include "base/enums.h"
+#include "base/stl_util.h"
#include "class_linker-inl.h"
#include "class_root.h"
#include "debugger.h"
@@ -106,26 +109,32 @@
}
ObjPtr<mirror::DexCache> ArtMethod::GetObsoleteDexCache() {
+ PointerSize pointer_size = kRuntimePointerSize;
DCHECK(!Runtime::Current()->IsAotCompiler()) << PrettyMethod();
DCHECK(IsObsolete());
ObjPtr<mirror::ClassExt> ext(GetDeclaringClass()->GetExtData());
- CHECK(!ext.IsNull());
- ObjPtr<mirror::PointerArray> obsolete_methods(ext->GetObsoleteMethods());
- CHECK(!obsolete_methods.IsNull());
- DCHECK(ext->GetObsoleteDexCaches() != nullptr);
- int32_t len = obsolete_methods->GetLength();
- DCHECK_EQ(len, ext->GetObsoleteDexCaches()->GetLength());
+ ObjPtr<mirror::PointerArray> obsolete_methods(ext.IsNull() ? nullptr : ext->GetObsoleteMethods());
+ int32_t len = (obsolete_methods.IsNull() ? 0 : obsolete_methods->GetLength());
+ DCHECK(len == 0 || len == ext->GetObsoleteDexCaches()->GetLength())
+ << "len=" << len << " ext->GetObsoleteDexCaches()=" << ext->GetObsoleteDexCaches();
// Using kRuntimePointerSize (instead of using the image's pointer size) is fine since images
// should never have obsolete methods in them so they should always be the same.
- PointerSize pointer_size = kRuntimePointerSize;
- DCHECK_EQ(kRuntimePointerSize, Runtime::Current()->GetClassLinker()->GetImagePointerSize());
+ DCHECK_EQ(pointer_size, Runtime::Current()->GetClassLinker()->GetImagePointerSize());
for (int32_t i = 0; i < len; i++) {
if (this == obsolete_methods->GetElementPtrSize<ArtMethod*>(i, pointer_size)) {
return ext->GetObsoleteDexCaches()->Get(i);
}
}
- LOG(FATAL) << "This method does not appear in the obsolete map of its class!";
- UNREACHABLE();
+ CHECK(GetDeclaringClass()->IsObsoleteObject())
+ << "This non-structurally obsolete method does not appear in the obsolete map of its class: "
+ << GetDeclaringClass()->PrettyClass() << " Searched " << len << " caches.";
+ CHECK_EQ(this,
+ std::clamp(this,
+ &(*GetDeclaringClass()->GetMethods(pointer_size).begin()),
+ &(*GetDeclaringClass()->GetMethods(pointer_size).end())))
+ << "class is marked as structurally obsolete method but not found in normal obsolete-map "
+ << "despite not being the original method pointer for " << GetDeclaringClass()->PrettyClass();
+ return GetDeclaringClass()->GetDexCache();
}
uint16_t ArtMethod::FindObsoleteDexClassDefIndex() {