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() {