Consolidate updating of reflective Field/Method references

Previously we used several different visitors to update Field &
Method references for structural redefinition. We also did not visit
or update JVMTI based references.

This consolidates all the visitors to a single
Runtime::VisitReflectiveTargets function with a single
ReflectiveTargetVisitor type. This simplifies the code around
structural redefinition and ensures that the reflective value holders
are in charge of the actual replacement.

Support was also added for walking internal openjdkjvmti references
for things like field-read/modification events.

Test: ./test.py --host
Bug: 134162467

Change-Id: Ic5fc1db7db0a30f947a1a67259dc024e149ebd57
diff --git a/runtime/mirror/dex_cache.cc b/runtime/mirror/dex_cache.cc
index f97f521..c2c47a5 100644
--- a/runtime/mirror/dex_cache.cc
+++ b/runtime/mirror/dex_cache.cc
@@ -25,6 +25,7 @@
 #include "object-inl.h"
 #include "object.h"
 #include "object_array-inl.h"
+#include "reflective_value_visitor.h"
 #include "runtime.h"
 #include "runtime_globals.h"
 #include "string.h"
@@ -172,6 +173,27 @@
                   dex_file->NumCallSiteIds());
 }
 
+void DexCache::VisitReflectiveTargets(ReflectiveValueVisitor* visitor) {
+  for (size_t i = 0; i < NumResolvedFields(); i++) {
+    auto pair(GetNativePairPtrSize(GetResolvedFields(), i, kRuntimePointerSize));
+    ArtField* new_val = visitor->VisitField(
+        pair.object, DexCacheSourceInfo(kSourceDexCacheResolvedField, pair.index, this));
+    if (UNLIKELY(new_val != pair.object)) {
+      pair.object = new_val;
+      SetNativePairPtrSize(GetResolvedFields(), i, pair, kRuntimePointerSize);
+    }
+  }
+  for (size_t i = 0; i < NumResolvedMethods(); i++) {
+    auto pair(GetNativePairPtrSize(GetResolvedMethods(), i, kRuntimePointerSize));
+    ArtMethod* new_val = visitor->VisitMethod(
+        pair.object, DexCacheSourceInfo(kSourceDexCacheResolvedMethod, pair.index, this));
+    if (UNLIKELY(new_val != pair.object)) {
+      pair.object = new_val;
+      SetNativePairPtrSize(GetResolvedMethods(), i, pair, kRuntimePointerSize);
+    }
+  }
+}
+
 bool DexCache::AddPreResolvedStringsArray() {
   DCHECK_EQ(NumPreResolvedStrings(), 0u);
   Thread* const self = Thread::Current();
diff --git a/runtime/mirror/dex_cache.h b/runtime/mirror/dex_cache.h
index b41443e..292db14 100644
--- a/runtime/mirror/dex_cache.h
+++ b/runtime/mirror/dex_cache.h
@@ -37,6 +37,7 @@
 class DexFile;
 union JValue;
 class LinearAlloc;
+class ReflectiveValueVisitor;
 class Thread;
 
 namespace mirror {
@@ -476,6 +477,8 @@
   // Returns true if we succeeded in adding the pre-resolved string array.
   bool AddPreResolvedStringsArray() REQUIRES_SHARED(Locks::mutator_lock_);
 
+  void VisitReflectiveTargets(ReflectiveValueVisitor* visitor) REQUIRES(Locks::mutator_lock_);
+
  private:
   void Init(const DexFile* dex_file,
             ObjPtr<String> location,
diff --git a/runtime/mirror/executable-inl.h b/runtime/mirror/executable-inl.h
index ce35d6e..f2d684a 100644
--- a/runtime/mirror/executable-inl.h
+++ b/runtime/mirror/executable-inl.h
@@ -20,6 +20,7 @@
 #include "executable.h"
 
 #include "object-inl.h"
+#include "reflective_value_visitor.h"
 #include "verify_object.h"
 
 namespace art {
@@ -37,10 +38,11 @@
   return GetFieldObject<mirror::Class>(DeclaringClassOffset());
 }
 
-template<typename Visitor, VerifyObjectFlags kVerifiyFlags>
-inline void Executable::VisitTarget(Visitor&& v) {
+template<VerifyObjectFlags kVerifiyFlags>
+inline void Executable::VisitTarget(ReflectiveValueVisitor* v) {
+  HeapReflectiveSourceInfo hrsi(kSourceJavaLangReflectExecutable, this);
   ArtMethod* orig = GetArtMethod<kVerifiyFlags>();
-  ArtMethod* new_target = v(orig);
+  ArtMethod* new_target = v->VisitMethod(orig, hrsi);
   if (orig != new_target) {
     SetArtMethod(new_target);
     SetDexMethodIndex(new_target->GetDexMethodIndex());
diff --git a/runtime/mirror/executable.h b/runtime/mirror/executable.h
index 8eca206..750a167 100644
--- a/runtime/mirror/executable.h
+++ b/runtime/mirror/executable.h
@@ -25,6 +25,7 @@
 
 struct ExecutableOffsets;
 class ArtMethod;
+class ReflectiveValueVisitor;
 
 namespace mirror {
 
@@ -41,9 +42,8 @@
     return reinterpret_cast64<ArtMethod*>(GetField64<kVerifyFlags>(ArtMethodOffset()));
   }
 
-  template <typename Visitor,
-            VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
-  inline void VisitTarget(Visitor&& v) REQUIRES(Locks::mutator_lock_);
+  template <VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
+  inline void VisitTarget(ReflectiveValueVisitor* v) REQUIRES(Locks::mutator_lock_);
 
   template <bool kTransactionActive = false,
             bool kCheckTransaction = true,
diff --git a/runtime/mirror/field-inl.h b/runtime/mirror/field-inl.h
index 6e82d6d..ac11be1 100644
--- a/runtime/mirror/field-inl.h
+++ b/runtime/mirror/field-inl.h
@@ -104,18 +104,6 @@
   SetFieldObject<kTransactionActive>(OFFSET_OF_OBJECT_MEMBER(Field, type_), type);
 }
 
-template<typename Visitor>
-inline void Field::VisitTarget(Visitor&& v) {
-  ArtField* orig = GetArtField(/*use_dex_cache*/false);
-  ArtField* new_value = v(orig);
-  if (orig != new_value) {
-    SetDexFieldIndex<false>(new_value->GetDexFieldIndex());
-    SetOffset<false>(new_value->GetOffset().Int32Value());
-    SetDeclaringClass<false>(new_value->GetDeclaringClass());
-  }
-  DCHECK_EQ(new_value, GetArtField(/*use_dex_cache*/false));
-}
-
 }  // namespace mirror
 }  // namespace art
 
diff --git a/runtime/mirror/field.cc b/runtime/mirror/field.cc
index 9a40006..aa071a8 100644
--- a/runtime/mirror/field.cc
+++ b/runtime/mirror/field.cc
@@ -24,6 +24,18 @@
 namespace art {
 namespace mirror {
 
+void Field::VisitTarget(ReflectiveValueVisitor* v) {
+  HeapReflectiveSourceInfo hrsi(kSourceJavaLangReflectField, this);
+  ArtField* orig = GetArtField(/*use_dex_cache*/false);
+  ArtField* new_value = v->VisitField(orig, hrsi);
+  if (orig != new_value) {
+    SetDexFieldIndex<false>(new_value->GetDexFieldIndex());
+    SetOffset<false>(new_value->GetOffset().Int32Value());
+    SetDeclaringClass<false>(new_value->GetDeclaringClass());
+  }
+  DCHECK_EQ(new_value, GetArtField(/*use_dex_cache*/false));
+}
+
 ArtField* Field::GetArtField(bool use_dex_cache) {
   ObjPtr<mirror::Class> declaring_class = GetDeclaringClass();
   if (UNLIKELY(declaring_class->IsProxyClass())) {
diff --git a/runtime/mirror/field.h b/runtime/mirror/field.h
index 89c86e3..2ed3452 100644
--- a/runtime/mirror/field.h
+++ b/runtime/mirror/field.h
@@ -29,6 +29,7 @@
 
 class ArtField;
 struct FieldOffsets;
+class ReflectiveValueVisitor;
 
 namespace mirror {
 
@@ -82,8 +83,7 @@
 
   // Used to modify the target of this Field object, if required for structural redefinition or some
   // other purpose.
-  template<typename Visitor>
-  inline void VisitTarget(Visitor&& v) REQUIRES(Locks::mutator_lock_);
+  void VisitTarget(ReflectiveValueVisitor* v) REQUIRES(Locks::mutator_lock_);
 
  private:
   // Padding required for matching alignment with the Java peer.
diff --git a/runtime/mirror/method_handle_impl-inl.h b/runtime/mirror/method_handle_impl-inl.h
index 0085642..932b434 100644
--- a/runtime/mirror/method_handle_impl-inl.h
+++ b/runtime/mirror/method_handle_impl-inl.h
@@ -39,20 +39,6 @@
       GetTargetMethod()->GetDeclaringClass() : GetTargetField()->GetDeclaringClass();
 }
 
-template<typename Visitor>
-inline void MethodHandle::VisitTarget(Visitor&& v) {
-  void* target = GetTargetField();
-  void* result;
-  if (GetHandleKind() < kFirstAccessorKind) {
-    result = v(GetTargetMethod());
-  } else {
-    result = v(GetTargetField());
-  }
-  if (result != target) {
-    SetField64<false>(ArtFieldOrMethodOffset(), reinterpret_cast<uintptr_t>(result));
-  }
-}
-
 }  // namespace mirror
 }  // namespace art
 
diff --git a/runtime/mirror/method_handle_impl.cc b/runtime/mirror/method_handle_impl.cc
index 433d4ba..dd25fc9 100644
--- a/runtime/mirror/method_handle_impl.cc
+++ b/runtime/mirror/method_handle_impl.cc
@@ -54,5 +54,20 @@
   return mh.Get();
 }
 
+void MethodHandle::VisitTarget(ReflectiveValueVisitor* v) {
+  void* target = GetTargetField();
+  void* result;
+  HeapReflectiveSourceInfo hrsi(kSourceJavaLangInvokeMethodHandle, this);
+  if (GetHandleKind() < kFirstAccessorKind) {
+    result = v->VisitMethod(GetTargetMethod(), hrsi);
+  } else {
+    result = v->VisitField(GetTargetField(), hrsi);
+  }
+  if (result != target) {
+    SetField64<false>(ArtFieldOrMethodOffset(), reinterpret_cast<uintptr_t>(result));
+  }
+}
+
+
 }  // namespace mirror
 }  // namespace art
diff --git a/runtime/mirror/method_handle_impl.h b/runtime/mirror/method_handle_impl.h
index 357ec9d..54aa0c9 100644
--- a/runtime/mirror/method_handle_impl.h
+++ b/runtime/mirror/method_handle_impl.h
@@ -28,6 +28,7 @@
 
 struct MethodHandleOffsets;
 struct MethodHandleImplOffsets;
+class ReflectiveValueVisitor;
 
 namespace mirror {
 
@@ -89,8 +90,7 @@
 
   // Used when classes become structurally obsolete to change the MethodHandle to refer to the new
   // method or field.
-  template<typename Visitor>
-  void VisitTarget(Visitor&& v) REQUIRES(Locks::mutator_lock_);
+  void VisitTarget(ReflectiveValueVisitor* v) REQUIRES(Locks::mutator_lock_);
 
  protected:
   void Initialize(uintptr_t art_field_or_method, Kind kind, Handle<MethodType> method_type)
diff --git a/runtime/mirror/var_handle-inl.h b/runtime/mirror/var_handle-inl.h
deleted file mode 100644
index d3f582d..0000000
--- a/runtime/mirror/var_handle-inl.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_RUNTIME_MIRROR_VAR_HANDLE_INL_H_
-#define ART_RUNTIME_MIRROR_VAR_HANDLE_INL_H_
-
-#include "var_handle.h"
-
-namespace art {
-class ArtField;
-
-namespace mirror {
-
-template<typename Visitor>
-inline void FieldVarHandle::VisitTarget(Visitor&& v) {
-  ArtField* orig = GetField();
-  ArtField* new_value = v(orig);
-  if (orig != new_value) {
-    SetField64</*kTransactionActive*/ false>(ArtFieldOffset(),
-                                             reinterpret_cast<uintptr_t>(new_value));
-  }
-}
-
-}  // namespace mirror
-}  // namespace art
-
-#endif  // ART_RUNTIME_MIRROR_VAR_HANDLE_INL_H_
diff --git a/runtime/mirror/var_handle.cc b/runtime/mirror/var_handle.cc
index d887b5a..6d5ff2c 100644
--- a/runtime/mirror/var_handle.cc
+++ b/runtime/mirror/var_handle.cc
@@ -2032,5 +2032,16 @@
   UNREACHABLE();
 }
 
+void FieldVarHandle::VisitTarget(ReflectiveValueVisitor* v) {
+  ArtField* orig = GetField();
+  ArtField* new_value =
+      v->VisitField(orig, HeapReflectiveSourceInfo(kSourceJavaLangInvokeFieldVarHandle, this));
+  if (orig != new_value) {
+    SetField64</*kTransactionActive*/ false>(ArtFieldOffset(),
+                                             reinterpret_cast<uintptr_t>(new_value));
+  }
+}
+
+
 }  // namespace mirror
 }  // namespace art
diff --git a/runtime/mirror/var_handle.h b/runtime/mirror/var_handle.h
index ac78d98..02a0d8c 100644
--- a/runtime/mirror/var_handle.h
+++ b/runtime/mirror/var_handle.h
@@ -36,6 +36,7 @@
 struct ByteArrayViewVarHandleOffsets;
 struct ByteBufferViewVarHandleOffsets;
 
+class ReflectiveValueVisitor;
 class ShadowFrameGetter;
 
 namespace mirror {
@@ -198,8 +199,7 @@
   ArtField* GetField() REQUIRES_SHARED(Locks::mutator_lock_);
 
   // Used for updating var-handles to obsolete fields.
-  template<typename Visitor>
-  inline void VisitTarget(Visitor&& v) REQUIRES(Locks::mutator_lock_);
+  void VisitTarget(ReflectiveValueVisitor* v) REQUIRES(Locks::mutator_lock_);
 
  private:
   static MemberOffset ArtFieldOffset() {