Revert "Basic structural redefinition support"

This reverts commit c971eafeff43e4e26959a6e86b62ab0a8f1a6e1c.

Bug: 134162467

Reason for revert: Breaks on redefine-stress

Change-Id: I4e38da23d65b5b34b26b5ab537a3583328e078a4
diff --git a/openjdkjvmti/ti_heap.cc b/openjdkjvmti/ti_heap.cc
index b0511a9..81d1fc7 100644
--- a/openjdkjvmti/ti_heap.cc
+++ b/openjdkjvmti/ti_heap.cc
@@ -1618,10 +1618,11 @@
 
 namespace {
 
-using ObjectPtr = art::ObjPtr<art::mirror::Object>;
+using ArrayPtr = art::ObjPtr<art::mirror::Array>;
 
-static void ReplaceObjectReferences(ObjectPtr old_obj_ptr, ObjectPtr new_obj_ptr)
+static void ReplaceObjectReferences(ArrayPtr old_arr_ptr, ArrayPtr new_arr_ptr)
     REQUIRES(art::Locks::mutator_lock_,
+             art::Locks::user_code_suspension_lock_,
              art::Roles::uninterruptible_) {
   art::Runtime::Current()->GetHeap()->VisitObjectsPaused(
       [&](art::mirror::Object* ref) REQUIRES_SHARED(art::Locks::mutator_lock_) {
@@ -1629,31 +1630,21 @@
         class ResizeReferenceVisitor {
          public:
           using CompressedObj = art::mirror::CompressedReference<art::mirror::Object>;
-          ResizeReferenceVisitor(ObjectPtr old_arr, ObjectPtr new_arr)
-              : old_obj_(old_arr), new_obj_(new_arr) {}
+          ResizeReferenceVisitor(ArrayPtr old_arr, ArrayPtr new_arr)
+              : old_arr_(old_arr), new_arr_(new_arr) {}
 
-          // Ignore class roots.
-          void VisitRootIfNonNull(CompressedObj* root) const
-              REQUIRES_SHARED(art::Locks::mutator_lock_) {
-            if (root != nullptr) {
-              VisitRoot(root);
-            }
-          }
-          void VisitRoot(CompressedObj* root) const REQUIRES_SHARED(art::Locks::mutator_lock_) {
-            if (root->AsMirrorPtr() == old_obj_) {
-              root->Assign(new_obj_);
-              art::WriteBarrier::ForEveryFieldWrite(new_obj_);
-            }
-          }
+          // Ignore class roots. These do not need to be handled for arrays.
+          void VisitRootIfNonNull(CompressedObj* root ATTRIBUTE_UNUSED) const {}
+          void VisitRoot(CompressedObj* root ATTRIBUTE_UNUSED) const {}
 
           void operator()(art::ObjPtr<art::mirror::Object> obj,
                           art::MemberOffset off,
                           bool is_static ATTRIBUTE_UNUSED) const
               REQUIRES_SHARED(art::Locks::mutator_lock_) {
-            if (obj->GetFieldObject<art::mirror::Object>(off) == old_obj_) {
+            if (obj->GetFieldObject<art::mirror::Object>(off) == old_arr_) {
               LOG(DEBUG) << "Updating field at offset " << off.Uint32Value() << " of type "
                          << obj->GetClass()->PrettyClass();
-              obj->SetFieldObject</*transaction*/ false>(off, new_obj_);
+              obj->SetFieldObject</*transaction*/ false>(off, new_arr_);
             }
           }
 
@@ -1665,31 +1656,23 @@
           }
 
          private:
-          ObjectPtr old_obj_;
-          ObjectPtr new_obj_;
+          ArrayPtr old_arr_;
+          ArrayPtr new_arr_;
         };
 
-        ResizeReferenceVisitor rrv(old_obj_ptr, new_obj_ptr);
-        if (ref->IsClass()) {
-          // Class object native roots are the ArtField and ArtMethod 'declaring_class_' fields
-          // which we don't want to be messing with as it would break ref-visitor assumptions about
-          // what a class looks like. We want to keep the default behavior in other cases (such as
-          // dex-cache) though. Unfortunately there is no way to tell from the visitor where exactly
-          // the root came from.
-          // TODO It might be nice to have the visitors told where the reference came from.
-          ref->VisitReferences</*kVisitNativeRoots*/false>(rrv, rrv);
-        } else {
-          ref->VisitReferences</*kVisitNativeRoots*/true>(rrv, rrv);
-        }
+        ResizeReferenceVisitor rrv(old_arr_ptr, new_arr_ptr);
+        ref->VisitReferences(rrv, rrv);
       });
 }
 
-static void ReplaceStrongRoots(art::Thread* self, ObjectPtr old_obj_ptr, ObjectPtr new_obj_ptr)
-    REQUIRES(art::Locks::mutator_lock_, art::Roles::uninterruptible_) {
+static void ReplaceStrongRoots(art::Thread* self, ArrayPtr old_arr_ptr, ArrayPtr new_arr_ptr)
+    REQUIRES(art::Locks::mutator_lock_,
+             art::Locks::user_code_suspension_lock_,
+             art::Roles::uninterruptible_) {
   // replace root references expcept java frames.
   struct ResizeRootVisitor : public art::RootVisitor {
    public:
-    ResizeRootVisitor(ObjectPtr new_val, ObjectPtr old_val)
+    ResizeRootVisitor(ArrayPtr new_val, ArrayPtr old_val)
         : new_val_(new_val), old_val_(old_val) {}
 
     // TODO It's somewhat annoying to have to have this function implemented twice. It might be
@@ -1703,16 +1686,7 @@
           // Java frames might have the JIT doing optimizations (for example loop-unrolling or
           // eliding bounds checks) so we need deopt them once we're done here.
           if (info.GetType() == art::RootType::kRootJavaFrame) {
-            const art::JavaFrameRootInfo& jfri =
-                art::down_cast<const art::JavaFrameRootInfo&>(info);
-            if (jfri.GetVReg() == art::JavaFrameRootInfo::kMethodDeclaringClass) {
-              info.Describe(LOG_STREAM(INFO) << "Not changing declaring-class during stack walk. "
-                                                "Found obsolete java frame id ");
-              continue;
-            } else {
-              info.Describe(LOG_STREAM(INFO) << "Found java frame id ");
-              threads_with_roots_.insert(info.GetThreadId());
-            }
+            threads_with_roots_.insert(info.GetThreadId());
           }
           *obj = new_val_.Ptr();
         }
@@ -1729,16 +1703,7 @@
           // Java frames might have the JIT doing optimizations (for example loop-unrolling or
           // eliding bounds checks) so we need deopt them once we're done here.
           if (info.GetType() == art::RootType::kRootJavaFrame) {
-            const art::JavaFrameRootInfo& jfri =
-                art::down_cast<const art::JavaFrameRootInfo&>(info);
-            if (jfri.GetVReg() == art::JavaFrameRootInfo::kMethodDeclaringClass) {
-              info.Describe(LOG_STREAM(INFO) << "Not changing declaring-class during stack walk. "
-                                                "Found obsolete java frame id ");
-              continue;
-            } else {
-              info.Describe(LOG_STREAM(INFO) << "Found java frame id ");
-              threads_with_roots_.insert(info.GetThreadId());
-            }
+            threads_with_roots_.insert(info.GetThreadId());
           }
           obj->Assign(new_val_);
         }
@@ -1750,11 +1715,11 @@
     }
 
    private:
-    ObjectPtr new_val_;
-    ObjectPtr old_val_;
+    ArrayPtr new_val_;
+    ArrayPtr old_val_;
     std::unordered_set<uint32_t> threads_with_roots_;
   };
-  ResizeRootVisitor rrv(new_obj_ptr, old_obj_ptr);
+  ResizeRootVisitor rrv(new_arr_ptr, old_arr_ptr);
   art::Runtime::Current()->VisitRoots(&rrv, art::VisitRootFlags::kVisitRootFlagAllRoots);
   // Handle java Frames. Annoyingly the JIT can embed information about the length of the array into
   // the compiled code. By changing the length of the array we potentially invalidate these
@@ -1767,7 +1732,6 @@
       art::Thread* t = thread_list->FindThreadByThreadId(id);
       CHECK(t != nullptr) << "id " << id << " does not refer to a valid thread."
                           << " Where did the roots come from?";
-      LOG(DEBUG) << "Instrumenting thread stack of thread " << *t;
       // TODO Use deopt manager. We need a version that doesn't acquire all the locks we
       // already have.
       // TODO We technically only need to do this if the frames are not already being interpreted.
@@ -1779,9 +1743,11 @@
 
 static void ReplaceWeakRoots(art::Thread* self,
                              EventHandler* event_handler,
-                             ObjectPtr old_obj_ptr,
-                             ObjectPtr new_obj_ptr)
-    REQUIRES(art::Locks::mutator_lock_, art::Roles::uninterruptible_) {
+                             ArrayPtr old_arr_ptr,
+                             ArrayPtr new_arr_ptr)
+    REQUIRES(art::Locks::mutator_lock_,
+             art::Locks::user_code_suspension_lock_,
+             art::Roles::uninterruptible_) {
   // Handle tags. We want to do this seprately from other weak-refs (handled below) because we need
   // to send additional events and handle cases where the agent might have tagged the new
   // replacement object during the VMObjectAlloc. We do this by removing all tags associated with
@@ -1801,8 +1767,8 @@
     // Get the tags and clear them (so we don't need to special-case the normal weak-ref visitor)
     jlong new_tag = 0;
     jlong obsolete_tag = 0;
-    bool had_new_tag = env->object_tag_table->RemoveLocked(new_obj_ptr, &new_tag);
-    bool had_obsolete_tag = env->object_tag_table->RemoveLocked(old_obj_ptr, &obsolete_tag);
+    bool had_new_tag = env->object_tag_table->RemoveLocked(new_arr_ptr, &new_tag);
+    bool had_obsolete_tag = env->object_tag_table->RemoveLocked(old_arr_ptr, &obsolete_tag);
     // Dispatch event.
     if (had_obsolete_tag || had_new_tag) {
       event_handler->DispatchEventOnEnv<ArtJvmtiEvent::kObsoleteObjectCreated>(env,
@@ -1813,56 +1779,60 @@
       non_obsolete_tags[env] = new_tag;
     }
     // After weak-ref update we need to go back and re-add obsoletes. We wait to avoid having to
-    // deal with the visit-weaks overwriting the initial new_obj_ptr tag and generally making things
+    // deal with the visit-weaks overwriting the initial new_arr_ptr tag and generally making things
     // difficult.
     env->object_tag_table->Unlock();
   });
   // Handle weak-refs.
   struct ReplaceWeaksVisitor : public art::IsMarkedVisitor {
    public:
-    ReplaceWeaksVisitor(ObjectPtr old_obj, ObjectPtr new_obj)
-        : old_obj_(old_obj), new_obj_(new_obj) {}
+    ReplaceWeaksVisitor(ArrayPtr old_arr, ArrayPtr new_arr)
+        : old_arr_(old_arr), new_arr_(new_arr) {}
 
     art::mirror::Object* IsMarked(art::mirror::Object* obj)
         REQUIRES_SHARED(art::Locks::mutator_lock_) {
-      if (obj == old_obj_) {
-        return new_obj_.Ptr();
+      if (obj == old_arr_) {
+        return new_arr_.Ptr();
       } else {
         return obj;
       }
     }
 
    private:
-    ObjectPtr old_obj_;
-    ObjectPtr new_obj_;
+    ArrayPtr old_arr_;
+    ArrayPtr new_arr_;
   };
-  ReplaceWeaksVisitor rwv(old_obj_ptr, new_obj_ptr);
+  ReplaceWeaksVisitor rwv(old_arr_ptr, new_arr_ptr);
   art::Runtime::Current()->SweepSystemWeaks(&rwv);
-  // Re-add the object tags. At this point all weak-references to the old_obj_ptr are gone.
+  // Re-add the object tags. At this point all weak-references to the old_arr_ptr are gone.
   event_handler->ForEachEnv(self, [&](ArtJvmTiEnv* env) {
     // Cannot have REQUIRES(art::Locks::mutator_lock_) since ForEachEnv doesn't require it.
     art::Locks::mutator_lock_->AssertExclusiveHeld(self);
     env->object_tag_table->Lock();
     if (obsolete_tags.find(env) != obsolete_tags.end()) {
-      env->object_tag_table->SetLocked(old_obj_ptr, obsolete_tags[env]);
+      env->object_tag_table->SetLocked(old_arr_ptr, obsolete_tags[env]);
     }
     if (non_obsolete_tags.find(env) != non_obsolete_tags.end()) {
-      env->object_tag_table->SetLocked(new_obj_ptr, non_obsolete_tags[env]);
+      env->object_tag_table->SetLocked(new_arr_ptr, non_obsolete_tags[env]);
     }
     env->object_tag_table->Unlock();
   });
 }
 
-}  // namespace
-
-void HeapExtensions::ReplaceReference(art::Thread* self,
-                                      art::ObjPtr<art::mirror::Object> old_obj_ptr,
-                                      art::ObjPtr<art::mirror::Object> new_obj_ptr) {
-  ReplaceObjectReferences(old_obj_ptr, new_obj_ptr);
-  ReplaceStrongRoots(self, old_obj_ptr, new_obj_ptr);
-  ReplaceWeakRoots(self, HeapExtensions::gEventHandler, old_obj_ptr, new_obj_ptr);
+static void PerformArrayReferenceReplacement(art::Thread* self,
+                                             EventHandler* event_handler,
+                                             ArrayPtr old_arr_ptr,
+                                             ArrayPtr new_arr_ptr)
+    REQUIRES(art::Locks::mutator_lock_,
+             art::Locks::user_code_suspension_lock_,
+             art::Roles::uninterruptible_) {
+  ReplaceObjectReferences(old_arr_ptr, new_arr_ptr);
+  ReplaceStrongRoots(self, old_arr_ptr, new_arr_ptr);
+  ReplaceWeakRoots(self, event_handler, old_arr_ptr, new_arr_ptr);
 }
 
+}  // namespace
+
 jvmtiError HeapExtensions::ChangeArraySize(jvmtiEnv* env, jobject arr, jsize new_size) {
   if (ArtJvmTiEnv::AsArtJvmTiEnv(env)->capabilities.can_tag_objects != 1) {
     return ERR(MUST_POSSESS_CAPABILITY);
@@ -1951,7 +1921,7 @@
       UNREACHABLE();
   }
   // Actually replace all the pointers.
-  ReplaceReference(self, old_arr.Get(), new_arr.Get());
+  PerformArrayReferenceReplacement(self, gEventHandler, old_arr.Get(), new_arr.Get());
   return OK;
 }