Set the declaring class of obsolete ArtMethods during redefinition

During structureal redefinition, we create a new class with a new set of
methods and fields and replace all old classes and their instances with
new class and newly created instances. We also retain the old class to
let any old methods that were still on stack during redefinition to
finish their execution. When replacing the old classes with new class we
should take care that the old method's declaring class isn't replaced.
It is very hard to ensure this since when walking the objects / roots
it is hard to check if the current reference is actually a declaring
class. We had this logic earlier but is a little brittle with addition
of any new roots.

This CL actually adds the logic so we can just replace all old class
reference with new class and we undo the changes for the old class's
methods and fields.

Bug: 206029744
Test: art/test.py
Change-Id: I96c5509f07562910cb1883cb5bf1236d01048213
diff --git a/openjdkjvmti/ti_redefine.cc b/openjdkjvmti/ti_redefine.cc
index 15cb6de..15ca423 100644
--- a/openjdkjvmti/ti_redefine.cc
+++ b/openjdkjvmti/ti_redefine.cc
@@ -2910,6 +2910,27 @@
   // be undone. This replaces the mirror::Class in 'holder' as well. It's magic!
   HeapExtensions::ReplaceReferences(driver_->self_, map);
 
+  // Undo the replacement of old_class with new_class for the methods / fields on the old_class.
+  // It is hard to ensure that we don't replace the declaring class of the old class field / methods
+  // isn't impacted by ReplaceReferences. It is just simpler to undo the replacement here.
+  std::for_each(
+      old_classes_vec.cbegin(),
+      old_classes_vec.cend(),
+      [](art::ObjPtr<art::mirror::Class> orig) REQUIRES_SHARED(art::Locks::mutator_lock_) {
+        orig->VisitMethods(
+            [&](art::ArtMethod* method) REQUIRES_SHARED(art::Locks::mutator_lock_) {
+              if (method->IsCopied()) {
+                // Copied methods have interfaces as their declaring class.
+                return;
+              }
+              method->SetDeclaringClass(orig);
+            },
+            art::kRuntimePointerSize);
+        orig->VisitFields([&](art::ArtField* field) REQUIRES_SHARED(art::Locks::mutator_lock_) {
+          field->SetDeclaringClass(orig);
+        });
+      });
+
   // Save the old class so that the JIT gc doesn't get confused by it being collected before the
   // jit code. This is also needed to keep the dex-caches of any obsolete methods live.
   for (auto [new_class, old_class] :