/*
 * Copyright (C) 2016 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.
 */

#include "ti_heap.h"

#include "art_field-inl.h"
#include "art_jvmti.h"
#include "base/macros.h"
#include "base/mutex.h"
#include "class_linker.h"
#include "dex/primitive.h"
#include "gc/heap-visit-objects-inl.h"
#include "gc/heap.h"
#include "gc_root-inl.h"
#include "java_frame_root_info.h"
#include "jni/jni_env_ext.h"
#include "jni/jni_internal.h"
#include "jvmti_weak_table-inl.h"
#include "mirror/class.h"
#include "mirror/object-inl.h"
#include "mirror/object_array-inl.h"
#include "obj_ptr-inl.h"
#include "object_tagging.h"
#include "runtime.h"
#include "scoped_thread_state_change-inl.h"
#include "stack.h"
#include "thread-inl.h"
#include "thread_list.h"

namespace openjdkjvmti {

namespace {

struct IndexCache {
  // The number of interface fields implemented by the class. This is a prefix to all assigned
  // field indices.
  size_t interface_fields;

  // It would be nice to also cache the following, but it is complicated to wire up into the
  // generic visit:
  // The number of fields in interfaces and superclasses. This is the first index assigned to
  // fields of the class.
  // size_t superclass_fields;
};
using IndexCachingTable = JvmtiWeakTable<IndexCache>;

static IndexCachingTable gIndexCachingTable;

// Report the contents of a string, if a callback is set.
jint ReportString(art::ObjPtr<art::mirror::Object> obj,
                  jvmtiEnv* env,
                  ObjectTagTable* tag_table,
                  const jvmtiHeapCallbacks* cb,
                  const void* user_data) REQUIRES_SHARED(art::Locks::mutator_lock_) {
  if (UNLIKELY(cb->string_primitive_value_callback != nullptr) && obj->IsString()) {
    art::ObjPtr<art::mirror::String> str = obj->AsString();
    int32_t string_length = str->GetLength();
    JvmtiUniquePtr<uint16_t[]> data;

    if (string_length > 0) {
      jvmtiError alloc_error;
      data = AllocJvmtiUniquePtr<uint16_t[]>(env, string_length, &alloc_error);
      if (data == nullptr) {
        // TODO: Not really sure what to do here. Should we abort the iteration and go all the way
        //       back? For now just warn.
        LOG(WARNING) << "Unable to allocate buffer for string reporting! Silently dropping value."
                     << " >" << str->ToModifiedUtf8() << "<";
        return 0;
      }

      if (str->IsCompressed()) {
        uint8_t* compressed_data = str->GetValueCompressed();
        for (int32_t i = 0; i != string_length; ++i) {
          data[i] = compressed_data[i];
        }
      } else {
        // Can copy directly.
        memcpy(data.get(), str->GetValue(), string_length * sizeof(uint16_t));
      }
    }

    const jlong class_tag = tag_table->GetTagOrZero(obj->GetClass());
    jlong string_tag = tag_table->GetTagOrZero(obj.Ptr());
    const jlong saved_string_tag = string_tag;

    jint result = cb->string_primitive_value_callback(class_tag,
                                                      obj->SizeOf(),
                                                      &string_tag,
                                                      data.get(),
                                                      string_length,
                                                      const_cast<void*>(user_data));
    if (string_tag != saved_string_tag) {
      tag_table->Set(obj.Ptr(), string_tag);
    }

    return result;
  }
  return 0;
}

// Report the contents of a primitive array, if a callback is set.
jint ReportPrimitiveArray(art::ObjPtr<art::mirror::Object> obj,
                          jvmtiEnv* env,
                          ObjectTagTable* tag_table,
                          const jvmtiHeapCallbacks* cb,
                          const void* user_data) REQUIRES_SHARED(art::Locks::mutator_lock_) {
  if (UNLIKELY(cb->array_primitive_value_callback != nullptr) &&
      obj->IsArrayInstance() &&
      !obj->IsObjectArray()) {
    art::ObjPtr<art::mirror::Array> array = obj->AsArray();
    int32_t array_length = array->GetLength();
    size_t component_size = array->GetClass()->GetComponentSize();
    art::Primitive::Type art_prim_type = array->GetClass()->GetComponentType()->GetPrimitiveType();
    jvmtiPrimitiveType prim_type =
        static_cast<jvmtiPrimitiveType>(art::Primitive::Descriptor(art_prim_type)[0]);
    DCHECK(prim_type == JVMTI_PRIMITIVE_TYPE_BOOLEAN ||
           prim_type == JVMTI_PRIMITIVE_TYPE_BYTE ||
           prim_type == JVMTI_PRIMITIVE_TYPE_CHAR ||
           prim_type == JVMTI_PRIMITIVE_TYPE_SHORT ||
           prim_type == JVMTI_PRIMITIVE_TYPE_INT ||
           prim_type == JVMTI_PRIMITIVE_TYPE_LONG ||
           prim_type == JVMTI_PRIMITIVE_TYPE_FLOAT ||
           prim_type == JVMTI_PRIMITIVE_TYPE_DOUBLE);

    const jlong class_tag = tag_table->GetTagOrZero(obj->GetClass());
    jlong array_tag = tag_table->GetTagOrZero(obj.Ptr());
    const jlong saved_array_tag = array_tag;

    jint result;
    if (array_length == 0) {
      result = cb->array_primitive_value_callback(class_tag,
                                                  obj->SizeOf(),
                                                  &array_tag,
                                                  0,
                                                  prim_type,
                                                  nullptr,
                                                  const_cast<void*>(user_data));
    } else {
      jvmtiError alloc_error;
      JvmtiUniquePtr<char[]> data = AllocJvmtiUniquePtr<char[]>(env,
                                                                array_length * component_size,
                                                                &alloc_error);
      if (data == nullptr) {
        // TODO: Not really sure what to do here. Should we abort the iteration and go all the way
        //       back? For now just warn.
        LOG(WARNING) << "Unable to allocate buffer for array reporting! Silently dropping value.";
        return 0;
      }

      memcpy(data.get(), array->GetRawData(component_size, 0), array_length * component_size);

      result = cb->array_primitive_value_callback(class_tag,
                                                  obj->SizeOf(),
                                                  &array_tag,
                                                  array_length,
                                                  prim_type,
                                                  data.get(),
                                                  const_cast<void*>(user_data));
    }

    if (array_tag != saved_array_tag) {
      tag_table->Set(obj.Ptr(), array_tag);
    }

    return result;
  }
  return 0;
}

template <typename UserData>
bool VisitorFalse(art::ObjPtr<art::mirror::Object> obj ATTRIBUTE_UNUSED,
                  art::ObjPtr<art::mirror::Class> klass ATTRIBUTE_UNUSED,
                  art::ArtField& field ATTRIBUTE_UNUSED,
                  size_t field_index ATTRIBUTE_UNUSED,
                  UserData* user_data ATTRIBUTE_UNUSED) {
  return false;
}

template <typename UserData, bool kCallVisitorOnRecursion>
class FieldVisitor {
 public:
  // Report the contents of a primitive fields of the given object, if a callback is set.
  template <typename StaticPrimitiveVisitor,
            typename StaticReferenceVisitor,
            typename InstancePrimitiveVisitor,
            typename InstanceReferenceVisitor>
  static bool ReportFields(art::ObjPtr<art::mirror::Object> obj,
                           UserData* user_data,
                           StaticPrimitiveVisitor& static_prim_visitor,
                           StaticReferenceVisitor& static_ref_visitor,
                           InstancePrimitiveVisitor& instance_prim_visitor,
                           InstanceReferenceVisitor& instance_ref_visitor)
      REQUIRES_SHARED(art::Locks::mutator_lock_) {
    FieldVisitor fv(user_data);

    if (obj->IsClass()) {
      // When visiting a class, we only visit the static fields of the given class. No field of
      // superclasses is visited.
      art::ObjPtr<art::mirror::Class> klass = obj->AsClass();
      // Only report fields on resolved classes. We need valid field data.
      if (!klass->IsResolved()) {
        return false;
      }
      return fv.ReportFieldsImpl(nullptr,
                                 obj->AsClass(),
                                 obj->AsClass()->IsInterface(),
                                 static_prim_visitor,
                                 static_ref_visitor,
                                 instance_prim_visitor,
                                 instance_ref_visitor);
    } else {
      // See comment above. Just double-checking here, but an instance *should* mean the class was
      // resolved.
      DCHECK(obj->GetClass()->IsResolved() || obj->GetClass()->IsErroneousResolved());
      return fv.ReportFieldsImpl(obj,
                                 obj->GetClass(),
                                 false,
                                 static_prim_visitor,
                                 static_ref_visitor,
                                 instance_prim_visitor,
                                 instance_ref_visitor);
    }
  }

 private:
  explicit FieldVisitor(UserData* user_data) : user_data_(user_data) {}

  // Report the contents of fields of the given object. If obj is null, report the static fields,
  // otherwise the instance fields.
  template <typename StaticPrimitiveVisitor,
            typename StaticReferenceVisitor,
            typename InstancePrimitiveVisitor,
            typename InstanceReferenceVisitor>
  bool ReportFieldsImpl(art::ObjPtr<art::mirror::Object> obj,
                        art::ObjPtr<art::mirror::Class> klass,
                        bool skip_java_lang_object,
                        StaticPrimitiveVisitor& static_prim_visitor,
                        StaticReferenceVisitor& static_ref_visitor,
                        InstancePrimitiveVisitor& instance_prim_visitor,
                        InstanceReferenceVisitor& instance_ref_visitor)
      REQUIRES_SHARED(art::Locks::mutator_lock_) {
    // Compute the offset of field indices.
    size_t interface_field_count = CountInterfaceFields(klass);

    size_t tmp;
    bool aborted = ReportFieldsRecursive(obj,
                                         klass,
                                         interface_field_count,
                                         skip_java_lang_object,
                                         static_prim_visitor,
                                         static_ref_visitor,
                                         instance_prim_visitor,
                                         instance_ref_visitor,
                                         &tmp);
    return aborted;
  }

  // Visit primitive fields in an object (instance). Return true if the visit was aborted.
  template <typename StaticPrimitiveVisitor,
            typename StaticReferenceVisitor,
            typename InstancePrimitiveVisitor,
            typename InstanceReferenceVisitor>
  bool ReportFieldsRecursive(art::ObjPtr<art::mirror::Object> obj,
                             art::ObjPtr<art::mirror::Class> klass,
                             size_t interface_fields,
                             bool skip_java_lang_object,
                             StaticPrimitiveVisitor& static_prim_visitor,
                             StaticReferenceVisitor& static_ref_visitor,
                             InstancePrimitiveVisitor& instance_prim_visitor,
                             InstanceReferenceVisitor& instance_ref_visitor,
                             size_t* field_index_out)
      REQUIRES_SHARED(art::Locks::mutator_lock_) {
    DCHECK(klass != nullptr);
    size_t field_index;
    if (klass->GetSuperClass() == nullptr) {
      // j.l.Object. Start with the fields from interfaces.
      field_index = interface_fields;
      if (skip_java_lang_object) {
        *field_index_out = field_index;
        return false;
      }
    } else {
      // Report superclass fields.
      if (kCallVisitorOnRecursion) {
        if (ReportFieldsRecursive(obj,
                                  klass->GetSuperClass(),
                                  interface_fields,
                                  skip_java_lang_object,
                                  static_prim_visitor,
                                  static_ref_visitor,
                                  instance_prim_visitor,
                                  instance_ref_visitor,
                                  &field_index)) {
          return true;
        }
      } else {
        // Still call, but with empty visitor. This is required for correct counting.
        ReportFieldsRecursive(obj,
                              klass->GetSuperClass(),
                              interface_fields,
                              skip_java_lang_object,
                              VisitorFalse<UserData>,
                              VisitorFalse<UserData>,
                              VisitorFalse<UserData>,
                              VisitorFalse<UserData>,
                              &field_index);
      }
    }

    // Now visit fields for the current klass.

    for (auto& static_field : klass->GetSFields()) {
      if (static_field.IsPrimitiveType()) {
        if (static_prim_visitor(obj,
                                klass,
                                static_field,
                                field_index,
                                user_data_)) {
          return true;
        }
      } else {
        if (static_ref_visitor(obj,
                               klass,
                               static_field,
                               field_index,
                               user_data_)) {
          return true;
        }
      }
      field_index++;
    }

    for (auto& instance_field : klass->GetIFields()) {
      if (instance_field.IsPrimitiveType()) {
        if (instance_prim_visitor(obj,
                                  klass,
                                  instance_field,
                                  field_index,
                                  user_data_)) {
          return true;
        }
      } else {
        if (instance_ref_visitor(obj,
                                 klass,
                                 instance_field,
                                 field_index,
                                 user_data_)) {
          return true;
        }
      }
      field_index++;
    }

    *field_index_out = field_index;
    return false;
  }

  // Implements a visit of the implemented interfaces of a given class.
  template <typename T>
  struct RecursiveInterfaceVisit {
    static void VisitStatic(art::Thread* self, art::ObjPtr<art::mirror::Class> klass, T& visitor)
        REQUIRES_SHARED(art::Locks::mutator_lock_) {
      RecursiveInterfaceVisit rv;
      rv.Visit(self, klass, visitor);
    }

    void Visit(art::Thread* self, art::ObjPtr<art::mirror::Class> klass, T& visitor)
        REQUIRES_SHARED(art::Locks::mutator_lock_) {
      // First visit the parent, to get the order right.
      // (We do this in preparation for actual visiting of interface fields.)
      if (klass->GetSuperClass() != nullptr) {
        Visit(self, klass->GetSuperClass(), visitor);
      }
      for (uint32_t i = 0; i != klass->NumDirectInterfaces(); ++i) {
        art::ObjPtr<art::mirror::Class> inf_klass =
            art::mirror::Class::GetDirectInterface(self, klass, i);
        DCHECK(inf_klass != nullptr);
        VisitInterface(self, inf_klass, visitor);
      }
    }

    void VisitInterface(art::Thread* self, art::ObjPtr<art::mirror::Class> inf_klass, T& visitor)
        REQUIRES_SHARED(art::Locks::mutator_lock_) {
      auto it = visited_interfaces.find(inf_klass.Ptr());
      if (it != visited_interfaces.end()) {
        return;
      }
      visited_interfaces.insert(inf_klass.Ptr());

      // Let the visitor know about this one. Note that this order is acceptable, as the ordering
      // of these fields never matters for known visitors.
      visitor(inf_klass);

      // Now visit the superinterfaces.
      for (uint32_t i = 0; i != inf_klass->NumDirectInterfaces(); ++i) {
        art::ObjPtr<art::mirror::Class> super_inf_klass =
            art::mirror::Class::GetDirectInterface(self, inf_klass, i);
        DCHECK(super_inf_klass != nullptr);
        VisitInterface(self, super_inf_klass, visitor);
      }
    }

    std::unordered_set<art::mirror::Class*> visited_interfaces;
  };

  // Counting interface fields. Note that we cannot use the interface table, as that only contains
  // "non-marker" interfaces (= interfaces with methods).
  static size_t CountInterfaceFields(art::ObjPtr<art::mirror::Class> klass)
      REQUIRES_SHARED(art::Locks::mutator_lock_) {
    // Do we have a cached value?
    IndexCache tmp;
    if (gIndexCachingTable.GetTag(klass.Ptr(), &tmp)) {
      return tmp.interface_fields;
    }

    size_t count = 0;
    auto visitor = [&count](art::ObjPtr<art::mirror::Class> inf_klass)
        REQUIRES_SHARED(art::Locks::mutator_lock_) {
      DCHECK(inf_klass->IsInterface());
      DCHECK_EQ(0u, inf_klass->NumInstanceFields());
      count += inf_klass->NumStaticFields();
    };
    RecursiveInterfaceVisit<decltype(visitor)>::VisitStatic(art::Thread::Current(), klass, visitor);

    // Store this into the cache.
    tmp.interface_fields = count;
    gIndexCachingTable.Set(klass.Ptr(), tmp);

    return count;
  }

  UserData* user_data_;
};

// Debug helper. Prints the structure of an object.
template <bool kStatic, bool kRef>
struct DumpVisitor {
  static bool Callback(art::ObjPtr<art::mirror::Object> obj ATTRIBUTE_UNUSED,
                       art::ObjPtr<art::mirror::Class> klass ATTRIBUTE_UNUSED,
                       art::ArtField& field,
                       size_t field_index,
                       void* user_data ATTRIBUTE_UNUSED)
      REQUIRES_SHARED(art::Locks::mutator_lock_) {
    LOG(ERROR) << (kStatic ? "static " : "instance ")
               << (kRef ? "ref " : "primitive ")
               << field.PrettyField()
               << " @ "
               << field_index;
    return false;
  }
};
ATTRIBUTE_UNUSED
void DumpObjectFields(art::ObjPtr<art::mirror::Object> obj)
    REQUIRES_SHARED(art::Locks::mutator_lock_) {
  if (obj->IsClass()) {
    FieldVisitor<void, false>:: ReportFields(obj,
                                             nullptr,
                                             DumpVisitor<true, false>::Callback,
                                             DumpVisitor<true, true>::Callback,
                                             DumpVisitor<false, false>::Callback,
                                             DumpVisitor<false, true>::Callback);
  } else {
    FieldVisitor<void, true>::ReportFields(obj,
                                           nullptr,
                                           DumpVisitor<true, false>::Callback,
                                           DumpVisitor<true, true>::Callback,
                                           DumpVisitor<false, false>::Callback,
                                           DumpVisitor<false, true>::Callback);
  }
}

class ReportPrimitiveField {
 public:
  static bool Report(art::ObjPtr<art::mirror::Object> obj,
                     ObjectTagTable* tag_table,
                     const jvmtiHeapCallbacks* cb,
                     const void* user_data)
      REQUIRES_SHARED(art::Locks::mutator_lock_) {
    if (UNLIKELY(cb->primitive_field_callback != nullptr)) {
      jlong class_tag = tag_table->GetTagOrZero(obj->GetClass());
      ReportPrimitiveField rpf(tag_table, class_tag, cb, user_data);
      if (obj->IsClass()) {
        return FieldVisitor<ReportPrimitiveField, false>::ReportFields(
            obj,
            &rpf,
            ReportPrimitiveFieldCallback<true>,
            VisitorFalse<ReportPrimitiveField>,
            VisitorFalse<ReportPrimitiveField>,
            VisitorFalse<ReportPrimitiveField>);
      } else {
        return FieldVisitor<ReportPrimitiveField, true>::ReportFields(
            obj,
            &rpf,
            VisitorFalse<ReportPrimitiveField>,
            VisitorFalse<ReportPrimitiveField>,
            ReportPrimitiveFieldCallback<false>,
            VisitorFalse<ReportPrimitiveField>);
      }
    }
    return false;
  }


 private:
  ReportPrimitiveField(ObjectTagTable* tag_table,
                       jlong class_tag,
                       const jvmtiHeapCallbacks* cb,
                       const void* user_data)
      : tag_table_(tag_table), class_tag_(class_tag), cb_(cb), user_data_(user_data) {}

  template <bool kReportStatic>
  static bool ReportPrimitiveFieldCallback(art::ObjPtr<art::mirror::Object> obj,
                                           art::ObjPtr<art::mirror::Class> klass,
                                           art::ArtField& field,
                                           size_t field_index,
                                           ReportPrimitiveField* user_data)
      REQUIRES_SHARED(art::Locks::mutator_lock_) {
    art::Primitive::Type art_prim_type = field.GetTypeAsPrimitiveType();
    jvmtiPrimitiveType prim_type =
        static_cast<jvmtiPrimitiveType>(art::Primitive::Descriptor(art_prim_type)[0]);
    DCHECK(prim_type == JVMTI_PRIMITIVE_TYPE_BOOLEAN ||
           prim_type == JVMTI_PRIMITIVE_TYPE_BYTE ||
           prim_type == JVMTI_PRIMITIVE_TYPE_CHAR ||
           prim_type == JVMTI_PRIMITIVE_TYPE_SHORT ||
           prim_type == JVMTI_PRIMITIVE_TYPE_INT ||
           prim_type == JVMTI_PRIMITIVE_TYPE_LONG ||
           prim_type == JVMTI_PRIMITIVE_TYPE_FLOAT ||
           prim_type == JVMTI_PRIMITIVE_TYPE_DOUBLE);
    jvmtiHeapReferenceInfo info;
    info.field.index = field_index;

    jvalue value;
    memset(&value, 0, sizeof(jvalue));
    art::ObjPtr<art::mirror::Object> src = kReportStatic ? klass : obj;
    switch (art_prim_type) {
      case art::Primitive::Type::kPrimBoolean:
        value.z = field.GetBoolean(src) == 0 ? JNI_FALSE : JNI_TRUE;
        break;
      case art::Primitive::Type::kPrimByte:
        value.b = field.GetByte(src);
        break;
      case art::Primitive::Type::kPrimChar:
        value.c = field.GetChar(src);
        break;
      case art::Primitive::Type::kPrimShort:
        value.s = field.GetShort(src);
        break;
      case art::Primitive::Type::kPrimInt:
        value.i = field.GetInt(src);
        break;
      case art::Primitive::Type::kPrimLong:
        value.j = field.GetLong(src);
        break;
      case art::Primitive::Type::kPrimFloat:
        value.f = field.GetFloat(src);
        break;
      case art::Primitive::Type::kPrimDouble:
        value.d = field.GetDouble(src);
        break;
      case art::Primitive::Type::kPrimVoid:
      case art::Primitive::Type::kPrimNot: {
        LOG(FATAL) << "Should not reach here";
        UNREACHABLE();
      }
    }

    jlong obj_tag = user_data->tag_table_->GetTagOrZero(src.Ptr());
    const jlong saved_obj_tag = obj_tag;

    jint ret = user_data->cb_->primitive_field_callback(kReportStatic
                                                            ? JVMTI_HEAP_REFERENCE_STATIC_FIELD
                                                            : JVMTI_HEAP_REFERENCE_FIELD,
                                                        &info,
                                                        user_data->class_tag_,
                                                        &obj_tag,
                                                        value,
                                                        prim_type,
                                                        const_cast<void*>(user_data->user_data_));

    if (saved_obj_tag != obj_tag) {
      user_data->tag_table_->Set(src.Ptr(), obj_tag);
    }

    if ((ret & JVMTI_VISIT_ABORT) != 0) {
      return true;
    }

    return false;
  }

  ObjectTagTable* tag_table_;
  jlong class_tag_;
  const jvmtiHeapCallbacks* cb_;
  const void* user_data_;
};

struct HeapFilter {
  explicit HeapFilter(jint heap_filter)
      : filter_out_tagged((heap_filter & JVMTI_HEAP_FILTER_TAGGED) != 0),
        filter_out_untagged((heap_filter & JVMTI_HEAP_FILTER_UNTAGGED) != 0),
        filter_out_class_tagged((heap_filter & JVMTI_HEAP_FILTER_CLASS_TAGGED) != 0),
        filter_out_class_untagged((heap_filter & JVMTI_HEAP_FILTER_CLASS_UNTAGGED) != 0),
        any_filter(filter_out_tagged ||
                   filter_out_untagged ||
                   filter_out_class_tagged ||
                   filter_out_class_untagged) {
  }

  bool ShouldReportByHeapFilter(jlong tag, jlong class_tag) const {
    if (!any_filter) {
      return true;
    }

    if ((tag == 0 && filter_out_untagged) || (tag != 0 && filter_out_tagged)) {
      return false;
    }

    if ((class_tag == 0 && filter_out_class_untagged) ||
        (class_tag != 0 && filter_out_class_tagged)) {
      return false;
    }

    return true;
  }

  const bool filter_out_tagged;
  const bool filter_out_untagged;
  const bool filter_out_class_tagged;
  const bool filter_out_class_untagged;
  const bool any_filter;
};

}  // namespace

void HeapUtil::Register() {
  art::Runtime::Current()->AddSystemWeakHolder(&gIndexCachingTable);
}

void HeapUtil::Unregister() {
  art::Runtime::Current()->RemoveSystemWeakHolder(&gIndexCachingTable);
}

jvmtiError HeapUtil::IterateOverInstancesOfClass(jvmtiEnv* env,
                                                 jclass klass,
                                                 jvmtiHeapObjectFilter filter,
                                                 jvmtiHeapObjectCallback cb,
                                                 const void* user_data) {
  if (cb == nullptr || klass == nullptr) {
    return ERR(NULL_POINTER);
  }

  art::Thread* self = art::Thread::Current();
  art::ScopedObjectAccess soa(self);      // Now we know we have the shared lock.
  art::StackHandleScope<1> hs(self);

  art::ObjPtr<art::mirror::Object> klass_ptr(soa.Decode<art::mirror::Class>(klass));
  if (!klass_ptr->IsClass()) {
    return ERR(INVALID_CLASS);
  }
  art::Handle<art::mirror::Class> filter_klass(hs.NewHandle(klass_ptr->AsClass()));
  if (filter_klass->IsInterface()) {
    // nothing is an 'instance' of an interface so just return without walking anything.
    return OK;
  }

  ObjectTagTable* tag_table = ArtJvmTiEnv::AsArtJvmTiEnv(env)->object_tag_table.get();
  bool stop_reports = false;
  auto visitor = [&](art::mirror::Object* obj) REQUIRES_SHARED(art::Locks::mutator_lock_) {
    // Early return, as we can't really stop visiting.
    if (stop_reports) {
      return;
    }

    art::ScopedAssertNoThreadSuspension no_suspension("IterateOverInstancesOfClass");

    art::ObjPtr<art::mirror::Class> klass = obj->GetClass();

    if (filter_klass != nullptr && !filter_klass->IsAssignableFrom(klass)) {
      return;
    }

    jlong tag = 0;
    tag_table->GetTag(obj, &tag);
    if ((filter != JVMTI_HEAP_OBJECT_EITHER) &&
        ((tag == 0 && filter == JVMTI_HEAP_OBJECT_TAGGED) ||
         (tag != 0 && filter == JVMTI_HEAP_OBJECT_UNTAGGED))) {
      return;
    }

    jlong class_tag = 0;
    tag_table->GetTag(klass.Ptr(), &class_tag);

    jlong saved_tag = tag;
    jint ret = cb(class_tag, obj->SizeOf(), &tag, const_cast<void*>(user_data));

    stop_reports = (ret == JVMTI_ITERATION_ABORT);

    if (tag != saved_tag) {
      tag_table->Set(obj, tag);
    }
  };
  art::Runtime::Current()->GetHeap()->VisitObjects(visitor);

  return OK;
}

template <typename T>
static jvmtiError DoIterateThroughHeap(T fn,
                                       jvmtiEnv* env,
                                       ObjectTagTable* tag_table,
                                       jint heap_filter_int,
                                       jclass klass,
                                       const jvmtiHeapCallbacks* callbacks,
                                       const void* user_data) {
  if (callbacks == nullptr) {
    return ERR(NULL_POINTER);
  }

  art::Thread* self = art::Thread::Current();
  art::ScopedObjectAccess soa(self);      // Now we know we have the shared lock.

  bool stop_reports = false;
  const HeapFilter heap_filter(heap_filter_int);
  art::ObjPtr<art::mirror::Class> filter_klass = soa.Decode<art::mirror::Class>(klass);
  auto visitor = [&](art::mirror::Object* obj) REQUIRES_SHARED(art::Locks::mutator_lock_) {
    // Early return, as we can't really stop visiting.
    if (stop_reports) {
      return;
    }

    art::ScopedAssertNoThreadSuspension no_suspension("IterateThroughHeapCallback");

    jlong tag = 0;
    tag_table->GetTag(obj, &tag);

    jlong class_tag = 0;
    art::ObjPtr<art::mirror::Class> klass = obj->GetClass();
    tag_table->GetTag(klass.Ptr(), &class_tag);
    // For simplicity, even if we find a tag = 0, assume 0 = not tagged.

    if (!heap_filter.ShouldReportByHeapFilter(tag, class_tag)) {
      return;
    }

    if (filter_klass != nullptr) {
      if (filter_klass != klass) {
        return;
      }
    }

    jlong size = obj->SizeOf();

    jint length = -1;
    if (obj->IsArrayInstance()) {
      length = obj->AsArray()->GetLength();
    }

    jlong saved_tag = tag;
    jint ret = fn(obj, callbacks, class_tag, size, &tag, length, const_cast<void*>(user_data));

    if (tag != saved_tag) {
      tag_table->Set(obj, tag);
    }

    stop_reports = (ret & JVMTI_VISIT_ABORT) != 0;

    if (!stop_reports) {
      jint string_ret = ReportString(obj, env, tag_table, callbacks, user_data);
      stop_reports = (string_ret & JVMTI_VISIT_ABORT) != 0;
    }

    if (!stop_reports) {
      jint array_ret = ReportPrimitiveArray(obj, env, tag_table, callbacks, user_data);
      stop_reports = (array_ret & JVMTI_VISIT_ABORT) != 0;
    }

    if (!stop_reports) {
      stop_reports = ReportPrimitiveField::Report(obj, tag_table, callbacks, user_data);
    }
  };
  art::Runtime::Current()->GetHeap()->VisitObjects(visitor);

  return ERR(NONE);
}

jvmtiError HeapUtil::IterateThroughHeap(jvmtiEnv* env,
                                        jint heap_filter,
                                        jclass klass,
                                        const jvmtiHeapCallbacks* callbacks,
                                        const void* user_data) {
  auto JvmtiIterateHeap = [](art::mirror::Object* obj ATTRIBUTE_UNUSED,
                             const jvmtiHeapCallbacks* cb_callbacks,
                             jlong class_tag,
                             jlong size,
                             jlong* tag,
                             jint length,
                             void* cb_user_data)
      REQUIRES_SHARED(art::Locks::mutator_lock_) {
    return cb_callbacks->heap_iteration_callback(class_tag,
                                                 size,
                                                 tag,
                                                 length,
                                                 cb_user_data);
  };
  return DoIterateThroughHeap(JvmtiIterateHeap,
                              env,
                              ArtJvmTiEnv::AsArtJvmTiEnv(env)->object_tag_table.get(),
                              heap_filter,
                              klass,
                              callbacks,
                              user_data);
}

class FollowReferencesHelper final {
 public:
  FollowReferencesHelper(HeapUtil* h,
                         jvmtiEnv* jvmti_env,
                         art::ObjPtr<art::mirror::Object> initial_object,
                         const jvmtiHeapCallbacks* callbacks,
                         art::ObjPtr<art::mirror::Class> class_filter,
                         jint heap_filter,
                         const void* user_data)
      : env(jvmti_env),
        tag_table_(h->GetTags()),
        initial_object_(initial_object),
        callbacks_(callbacks),
        class_filter_(class_filter),
        heap_filter_(heap_filter),
        user_data_(user_data),
        start_(0),
        stop_reports_(false) {
  }

  void Init()
      REQUIRES_SHARED(art::Locks::mutator_lock_)
      REQUIRES(!*tag_table_->GetAllowDisallowLock()) {
    if (initial_object_.IsNull()) {
      CollectAndReportRootsVisitor carrv(this, tag_table_, &worklist_, &visited_);

      // We need precise info (e.g., vregs).
      constexpr art::VisitRootFlags kRootFlags = static_cast<art::VisitRootFlags>(
          art::VisitRootFlags::kVisitRootFlagAllRoots | art::VisitRootFlags::kVisitRootFlagPrecise);
      art::Runtime::Current()->VisitRoots(&carrv, kRootFlags);

      art::Runtime::Current()->VisitImageRoots(&carrv);
      stop_reports_ = carrv.IsStopReports();

      if (stop_reports_) {
        worklist_.clear();
      }
    } else {
      visited_.insert(initial_object_.Ptr());
      worklist_.push_back(initial_object_.Ptr());
    }
  }

  void Work()
      REQUIRES_SHARED(art::Locks::mutator_lock_)
      REQUIRES(!*tag_table_->GetAllowDisallowLock()) {
    // Currently implemented as a BFS. To lower overhead, we don't erase elements immediately
    // from the head of the work list, instead postponing until there's a gap that's "large."
    //
    // Alternatively, we can implement a DFS and use the work list as a stack.
    while (start_ < worklist_.size()) {
      art::mirror::Object* cur_obj = worklist_[start_];
      start_++;

      if (start_ >= kMaxStart) {
        worklist_.erase(worklist_.begin(), worklist_.begin() + start_);
        start_ = 0;
      }

      VisitObject(cur_obj);

      if (stop_reports_) {
        break;
      }
    }
  }

 private:
  class CollectAndReportRootsVisitor final : public art::RootVisitor {
   public:
    CollectAndReportRootsVisitor(FollowReferencesHelper* helper,
                                 ObjectTagTable* tag_table,
                                 std::vector<art::mirror::Object*>* worklist,
                                 std::unordered_set<art::mirror::Object*>* visited)
        : helper_(helper),
          tag_table_(tag_table),
          worklist_(worklist),
          visited_(visited),
          stop_reports_(false) {}

    void VisitRoots(art::mirror::Object*** roots, size_t count, const art::RootInfo& info)
        override
        REQUIRES_SHARED(art::Locks::mutator_lock_)
        REQUIRES(!*helper_->tag_table_->GetAllowDisallowLock()) {
      for (size_t i = 0; i != count; ++i) {
        AddRoot(*roots[i], info);
      }
    }

    void VisitRoots(art::mirror::CompressedReference<art::mirror::Object>** roots,
                    size_t count,
                    const art::RootInfo& info)
        override REQUIRES_SHARED(art::Locks::mutator_lock_)
        REQUIRES(!*helper_->tag_table_->GetAllowDisallowLock()) {
      for (size_t i = 0; i != count; ++i) {
        AddRoot(roots[i]->AsMirrorPtr(), info);
      }
    }

    bool IsStopReports() {
      return stop_reports_;
    }

   private:
    void AddRoot(art::mirror::Object* root_obj, const art::RootInfo& info)
        REQUIRES_SHARED(art::Locks::mutator_lock_)
        REQUIRES(!*tag_table_->GetAllowDisallowLock()) {
      if (stop_reports_) {
        return;
      }
      bool add_to_worklist = ReportRoot(root_obj, info);
      // We use visited_ to mark roots already so we do not need another set.
      if (visited_->find(root_obj) == visited_->end()) {
        if (add_to_worklist) {
          visited_->insert(root_obj);
          worklist_->push_back(root_obj);
        }
      }
    }

    // Remove NO_THREAD_SAFETY_ANALYSIS once ASSERT_CAPABILITY works correctly.
    art::Thread* FindThread(const art::RootInfo& info) NO_THREAD_SAFETY_ANALYSIS {
      art::Locks::thread_list_lock_->AssertExclusiveHeld(art::Thread::Current());
      return art::Runtime::Current()->GetThreadList()->FindThreadByThreadId(info.GetThreadId());
    }

    jvmtiHeapReferenceKind GetReferenceKind(const art::RootInfo& info,
                                            jvmtiHeapReferenceInfo* ref_info)
        REQUIRES_SHARED(art::Locks::mutator_lock_) {
      // TODO: Fill in ref_info.
      memset(ref_info, 0, sizeof(jvmtiHeapReferenceInfo));

      switch (info.GetType()) {
        case art::RootType::kRootJNIGlobal:
          return JVMTI_HEAP_REFERENCE_JNI_GLOBAL;

        case art::RootType::kRootJNILocal:
        {
          uint32_t thread_id = info.GetThreadId();
          ref_info->jni_local.thread_id = thread_id;

          art::Thread* thread = FindThread(info);
          if (thread != nullptr) {
            art::mirror::Object* thread_obj;
            if (thread->IsStillStarting()) {
              thread_obj = nullptr;
            } else {
              thread_obj = thread->GetPeerFromOtherThread();
            }
            if (thread_obj != nullptr) {
              ref_info->jni_local.thread_tag = tag_table_->GetTagOrZero(thread_obj);
            }
          }

          // TODO: We don't have this info.
          if (thread != nullptr) {
            ref_info->jni_local.depth = 0;
            art::ArtMethod* method = thread->GetCurrentMethod(nullptr,
                                                              /* check_suspended= */ true,
                                                              /* abort_on_error= */ false);
            if (method != nullptr) {
              ref_info->jni_local.method = art::jni::EncodeArtMethod(method);
            }
          }

          return JVMTI_HEAP_REFERENCE_JNI_LOCAL;
        }

        case art::RootType::kRootJavaFrame:
        {
          uint32_t thread_id = info.GetThreadId();
          ref_info->stack_local.thread_id = thread_id;

          art::Thread* thread = FindThread(info);
          if (thread != nullptr) {
            art::mirror::Object* thread_obj;
            if (thread->IsStillStarting()) {
              thread_obj = nullptr;
            } else {
              thread_obj = thread->GetPeerFromOtherThread();
            }
            if (thread_obj != nullptr) {
              ref_info->stack_local.thread_tag = tag_table_->GetTagOrZero(thread_obj);
            }
          }

          auto& java_info = static_cast<const art::JavaFrameRootInfo&>(info);
          ref_info->stack_local.slot = static_cast<jint>(java_info.GetVReg());
          const art::StackVisitor* visitor = java_info.GetVisitor();
          ref_info->stack_local.location =
              static_cast<jlocation>(visitor->GetDexPc(/* abort_on_failure= */ false));
          ref_info->stack_local.depth = static_cast<jint>(visitor->GetFrameDepth());
          art::ArtMethod* method = visitor->GetMethod();
          if (method != nullptr) {
            ref_info->stack_local.method = art::jni::EncodeArtMethod(method);
          }

          return JVMTI_HEAP_REFERENCE_STACK_LOCAL;
        }

        case art::RootType::kRootNativeStack:
        case art::RootType::kRootThreadBlock:
        case art::RootType::kRootThreadObject:
          return JVMTI_HEAP_REFERENCE_THREAD;

        case art::RootType::kRootStickyClass:
        case art::RootType::kRootInternedString:
          // Note: this isn't a root in the RI.
          return JVMTI_HEAP_REFERENCE_SYSTEM_CLASS;

        case art::RootType::kRootMonitorUsed:
        case art::RootType::kRootJNIMonitor:
          return JVMTI_HEAP_REFERENCE_MONITOR;

        case art::RootType::kRootFinalizing:
        case art::RootType::kRootDebugger:
        case art::RootType::kRootReferenceCleanup:
        case art::RootType::kRootVMInternal:
        case art::RootType::kRootUnknown:
          return JVMTI_HEAP_REFERENCE_OTHER;
      }
      LOG(FATAL) << "Unreachable";
      UNREACHABLE();
    }

    bool ReportRoot(art::mirror::Object* root_obj, const art::RootInfo& info)
        REQUIRES_SHARED(art::Locks::mutator_lock_)
        REQUIRES(!*tag_table_->GetAllowDisallowLock()) {
      jvmtiHeapReferenceInfo ref_info;
      jvmtiHeapReferenceKind kind = GetReferenceKind(info, &ref_info);
      jint result = helper_->ReportReference(kind, &ref_info, nullptr, root_obj);
      if ((result & JVMTI_VISIT_ABORT) != 0) {
        stop_reports_ = true;
      }
      return (result & JVMTI_VISIT_OBJECTS) != 0;
    }

   private:
    FollowReferencesHelper* helper_;
    ObjectTagTable* tag_table_;
    std::vector<art::mirror::Object*>* worklist_;
    std::unordered_set<art::mirror::Object*>* visited_;
    bool stop_reports_;
  };

  void VisitObject(art::mirror::Object* obj)
      REQUIRES_SHARED(art::Locks::mutator_lock_)
      REQUIRES(!*tag_table_->GetAllowDisallowLock()) {
    if (obj->IsClass()) {
      VisitClass(obj->AsClass());
      return;
    }
    if (obj->IsArrayInstance()) {
      VisitArray(obj);
      return;
    }

    // All instance fields.
    auto report_instance_field = [&](art::ObjPtr<art::mirror::Object> src,
                                     art::ObjPtr<art::mirror::Class> obj_klass ATTRIBUTE_UNUSED,
                                     art::ArtField& field,
                                     size_t field_index,
                                     void* user_data ATTRIBUTE_UNUSED)
        REQUIRES_SHARED(art::Locks::mutator_lock_)
        REQUIRES(!*tag_table_->GetAllowDisallowLock()) {
      art::ObjPtr<art::mirror::Object> field_value = field.GetObject(src);
      if (field_value != nullptr) {
        jvmtiHeapReferenceInfo reference_info;
        memset(&reference_info, 0, sizeof(reference_info));

        reference_info.field.index = field_index;

        jvmtiHeapReferenceKind kind =
            field.GetOffset().Int32Value() == art::mirror::Object::ClassOffset().Int32Value()
                ? JVMTI_HEAP_REFERENCE_CLASS
                : JVMTI_HEAP_REFERENCE_FIELD;
        const jvmtiHeapReferenceInfo* reference_info_ptr =
            kind == JVMTI_HEAP_REFERENCE_CLASS ? nullptr : &reference_info;

        return !ReportReferenceMaybeEnqueue(kind, reference_info_ptr, src.Ptr(), field_value.Ptr());
      }
      return false;
    };
    stop_reports_ = FieldVisitor<void, true>::ReportFields(obj,
                                                           nullptr,
                                                           VisitorFalse<void>,
                                                           VisitorFalse<void>,
                                                           VisitorFalse<void>,
                                                           report_instance_field);
    if (stop_reports_) {
      return;
    }

    jint string_ret = ReportString(obj, env, tag_table_, callbacks_, user_data_);
    stop_reports_ = (string_ret & JVMTI_VISIT_ABORT) != 0;
    if (stop_reports_) {
      return;
    }

    stop_reports_ = ReportPrimitiveField::Report(obj, tag_table_, callbacks_, user_data_);
  }

  void VisitArray(art::mirror::Object* array)
      REQUIRES_SHARED(art::Locks::mutator_lock_)
      REQUIRES(!*tag_table_->GetAllowDisallowLock()) {
    stop_reports_ = !ReportReferenceMaybeEnqueue(JVMTI_HEAP_REFERENCE_CLASS,
                                                 nullptr,
                                                 array,
                                                 array->GetClass());
    if (stop_reports_) {
      return;
    }

    if (array->IsObjectArray()) {
      art::mirror::ObjectArray<art::mirror::Object>* obj_array =
          array->AsObjectArray<art::mirror::Object>();
      int32_t length = obj_array->GetLength();
      for (int32_t i = 0; i != length; ++i) {
        art::mirror::Object* elem = obj_array->GetWithoutChecks(i);
        if (elem != nullptr) {
          jvmtiHeapReferenceInfo reference_info;
          reference_info.array.index = i;
          stop_reports_ = !ReportReferenceMaybeEnqueue(JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT,
                                                       &reference_info,
                                                       array,
                                                       elem);
          if (stop_reports_) {
            break;
          }
        }
      }
    } else {
      if (!stop_reports_) {
        jint array_ret = ReportPrimitiveArray(array, env, tag_table_, callbacks_, user_data_);
        stop_reports_ = (array_ret & JVMTI_VISIT_ABORT) != 0;
      }
    }
  }

  void VisitClass(art::mirror::Class* klass)
      REQUIRES_SHARED(art::Locks::mutator_lock_)
      REQUIRES(!*tag_table_->GetAllowDisallowLock()) {
    // TODO: Are erroneous classes reported? Are non-prepared ones? For now, just use resolved ones.
    if (!klass->IsResolved()) {
      return;
    }

    // Superclass.
    stop_reports_ = !ReportReferenceMaybeEnqueue(JVMTI_HEAP_REFERENCE_SUPERCLASS,
                                                 nullptr,
                                                 klass,
                                                 klass->GetSuperClass().Ptr());
    if (stop_reports_) {
      return;
    }

    // Directly implemented or extended interfaces.
    art::Thread* self = art::Thread::Current();
    art::StackHandleScope<1> hs(self);
    art::Handle<art::mirror::Class> h_klass(hs.NewHandle<art::mirror::Class>(klass));
    for (size_t i = 0; i < h_klass->NumDirectInterfaces(); ++i) {
      art::ObjPtr<art::mirror::Class> inf_klass =
          art::mirror::Class::ResolveDirectInterface(self, h_klass, i);
      if (inf_klass == nullptr) {
        // TODO: With a resolved class this should not happen...
        self->ClearException();
        break;
      }

      stop_reports_ = !ReportReferenceMaybeEnqueue(JVMTI_HEAP_REFERENCE_INTERFACE,
                                                   nullptr,
                                                   klass,
                                                   inf_klass.Ptr());
      if (stop_reports_) {
        return;
      }
    }

    // Classloader.
    // TODO: What about the boot classpath loader? We'll skip for now, but do we have to find the
    //       fake BootClassLoader?
    if (klass->GetClassLoader() != nullptr) {
      stop_reports_ = !ReportReferenceMaybeEnqueue(JVMTI_HEAP_REFERENCE_CLASS_LOADER,
                                                   nullptr,
                                                   klass,
                                                   klass->GetClassLoader());
      if (stop_reports_) {
        return;
      }
    }
    DCHECK_EQ(h_klass.Get(), klass);

    // Declared static fields.
    auto report_static_field = [&](art::ObjPtr<art::mirror::Object> obj ATTRIBUTE_UNUSED,
                                   art::ObjPtr<art::mirror::Class> obj_klass,
                                   art::ArtField& field,
                                   size_t field_index,
                                   void* user_data ATTRIBUTE_UNUSED)
        REQUIRES_SHARED(art::Locks::mutator_lock_)
        REQUIRES(!*tag_table_->GetAllowDisallowLock()) {
      art::ObjPtr<art::mirror::Object> field_value = field.GetObject(obj_klass);
      if (field_value != nullptr) {
        jvmtiHeapReferenceInfo reference_info;
        memset(&reference_info, 0, sizeof(reference_info));

        reference_info.field.index = static_cast<jint>(field_index);

        return !ReportReferenceMaybeEnqueue(JVMTI_HEAP_REFERENCE_STATIC_FIELD,
                                            &reference_info,
                                            obj_klass.Ptr(),
                                            field_value.Ptr());
      }
      return false;
    };
    stop_reports_ = FieldVisitor<void, false>::ReportFields(klass,
                                                            nullptr,
                                                            VisitorFalse<void>,
                                                            report_static_field,
                                                            VisitorFalse<void>,
                                                            VisitorFalse<void>);
    if (stop_reports_) {
      return;
    }

    stop_reports_ = ReportPrimitiveField::Report(klass, tag_table_, callbacks_, user_data_);
  }

  void MaybeEnqueue(art::mirror::Object* obj) REQUIRES_SHARED(art::Locks::mutator_lock_) {
    if (visited_.find(obj) == visited_.end()) {
      worklist_.push_back(obj);
      visited_.insert(obj);
    }
  }

  bool ReportReferenceMaybeEnqueue(jvmtiHeapReferenceKind kind,
                                   const jvmtiHeapReferenceInfo* reference_info,
                                   art::mirror::Object* referree,
                                   art::mirror::Object* referrer)
      REQUIRES_SHARED(art::Locks::mutator_lock_)
      REQUIRES(!*tag_table_->GetAllowDisallowLock()) {
    jint result = ReportReference(kind, reference_info, referree, referrer);
    if ((result & JVMTI_VISIT_ABORT) == 0) {
      if ((result & JVMTI_VISIT_OBJECTS) != 0) {
        MaybeEnqueue(referrer);
      }
      return true;
    } else {
      return false;
    }
  }

  jint ReportReference(jvmtiHeapReferenceKind kind,
                       const jvmtiHeapReferenceInfo* reference_info,
                       art::mirror::Object* referrer,
                       art::mirror::Object* referree)
      REQUIRES_SHARED(art::Locks::mutator_lock_)
      REQUIRES(!*tag_table_->GetAllowDisallowLock()) {
    if (referree == nullptr || stop_reports_) {
      return 0;
    }

    if (UNLIKELY(class_filter_ != nullptr) && class_filter_ != referree->GetClass()) {
      return JVMTI_VISIT_OBJECTS;
    }

    const jlong class_tag = tag_table_->GetTagOrZero(referree->GetClass());
    jlong tag = tag_table_->GetTagOrZero(referree);

    if (!heap_filter_.ShouldReportByHeapFilter(tag, class_tag)) {
      return JVMTI_VISIT_OBJECTS;
    }

    const jlong referrer_class_tag =
        referrer == nullptr ? 0 : tag_table_->GetTagOrZero(referrer->GetClass());
    const jlong size = static_cast<jlong>(referree->SizeOf());
    jlong saved_tag = tag;
    jlong referrer_tag = 0;
    jlong saved_referrer_tag = 0;
    jlong* referrer_tag_ptr;
    if (referrer == nullptr) {
      referrer_tag_ptr = nullptr;
    } else {
      if (referrer == referree) {
        referrer_tag_ptr = &tag;
      } else {
        referrer_tag = saved_referrer_tag = tag_table_->GetTagOrZero(referrer);
        referrer_tag_ptr = &referrer_tag;
      }
    }

    jint length = -1;
    if (referree->IsArrayInstance()) {
      length = referree->AsArray()->GetLength();
    }

    jint result = callbacks_->heap_reference_callback(kind,
                                                      reference_info,
                                                      class_tag,
                                                      referrer_class_tag,
                                                      size,
                                                      &tag,
                                                      referrer_tag_ptr,
                                                      length,
                                                      const_cast<void*>(user_data_));

    if (tag != saved_tag) {
      tag_table_->Set(referree, tag);
    }
    if (referrer_tag != saved_referrer_tag) {
      tag_table_->Set(referrer, referrer_tag);
    }

    return result;
  }

  jvmtiEnv* env;
  ObjectTagTable* tag_table_;
  art::ObjPtr<art::mirror::Object> initial_object_;
  const jvmtiHeapCallbacks* callbacks_;
  art::ObjPtr<art::mirror::Class> class_filter_;
  const HeapFilter heap_filter_;
  const void* user_data_;

  std::vector<art::mirror::Object*> worklist_;
  size_t start_;
  static constexpr size_t kMaxStart = 1000000U;

  std::unordered_set<art::mirror::Object*> visited_;

  bool stop_reports_;

  friend class CollectAndReportRootsVisitor;
};

jvmtiError HeapUtil::FollowReferences(jvmtiEnv* env,
                                      jint heap_filter,
                                      jclass klass,
                                      jobject initial_object,
                                      const jvmtiHeapCallbacks* callbacks,
                                      const void* user_data) {
  if (callbacks == nullptr) {
    return ERR(NULL_POINTER);
  }

  art::Thread* self = art::Thread::Current();

  art::gc::Heap* heap = art::Runtime::Current()->GetHeap();
  if (heap->IsGcConcurrentAndMoving()) {
    // Need to take a heap dump while GC isn't running. See the
    // comment in Heap::VisitObjects().
    heap->IncrementDisableMovingGC(self);
  }
  {
    art::ScopedObjectAccess soa(self);      // Now we know we have the shared lock.
    art::ScopedThreadSuspension sts(self, art::kWaitingForVisitObjects);
    art::ScopedSuspendAll ssa("FollowReferences");

    art::ObjPtr<art::mirror::Class> class_filter = klass == nullptr
        ? nullptr
        : art::ObjPtr<art::mirror::Class>::DownCast(self->DecodeJObject(klass));
    FollowReferencesHelper frh(this,
                               env,
                               self->DecodeJObject(initial_object),
                               callbacks,
                               class_filter,
                               heap_filter,
                               user_data);
    frh.Init();
    frh.Work();
  }
  if (heap->IsGcConcurrentAndMoving()) {
    heap->DecrementDisableMovingGC(self);
  }

  return ERR(NONE);
}

jvmtiError HeapUtil::GetLoadedClasses(jvmtiEnv* env,
                                      jint* class_count_ptr,
                                      jclass** classes_ptr) {
  if (class_count_ptr == nullptr || classes_ptr == nullptr) {
    return ERR(NULL_POINTER);
  }

  class ReportClassVisitor : public art::ClassVisitor {
   public:
    explicit ReportClassVisitor(art::Thread* self) : self_(self) {}

    bool operator()(art::ObjPtr<art::mirror::Class> klass)
        override REQUIRES_SHARED(art::Locks::mutator_lock_) {
      if (klass->IsLoaded() || klass->IsErroneous()) {
        classes_.push_back(self_->GetJniEnv()->AddLocalReference<jclass>(klass));
      }
      return true;
    }

    art::Thread* self_;
    std::vector<jclass> classes_;
  };

  art::Thread* self = art::Thread::Current();
  ReportClassVisitor rcv(self);
  {
    art::ScopedObjectAccess soa(self);
    art::Runtime::Current()->GetClassLinker()->VisitClasses(&rcv);
  }

  size_t size = rcv.classes_.size();
  jclass* classes = nullptr;
  jvmtiError alloc_ret = env->Allocate(static_cast<jlong>(size * sizeof(jclass)),
                                       reinterpret_cast<unsigned char**>(&classes));
  if (alloc_ret != ERR(NONE)) {
    return alloc_ret;
  }

  for (size_t i = 0; i < size; ++i) {
    classes[i] = rcv.classes_[i];
  }
  *classes_ptr = classes;
  *class_count_ptr = static_cast<jint>(size);

  return ERR(NONE);
}

jvmtiError HeapUtil::ForceGarbageCollection(jvmtiEnv* env ATTRIBUTE_UNUSED) {
  art::Runtime::Current()->GetHeap()->CollectGarbage(/* clear_soft_references= */ false);

  return ERR(NONE);
}

static constexpr jint kHeapIdDefault = 0;
static constexpr jint kHeapIdImage = 1;
static constexpr jint kHeapIdZygote = 2;
static constexpr jint kHeapIdApp = 3;

static jint GetHeapId(art::ObjPtr<art::mirror::Object> obj)
    REQUIRES_SHARED(art::Locks::mutator_lock_) {
  if (obj == nullptr) {
    return -1;
  }

  art::gc::Heap* const heap = art::Runtime::Current()->GetHeap();
  const art::gc::space::ContinuousSpace* const space =
      heap->FindContinuousSpaceFromObject(obj, true);
  jint heap_type = kHeapIdApp;
  if (space != nullptr) {
    if (space->IsZygoteSpace()) {
      heap_type = kHeapIdZygote;
    } else if (space->IsImageSpace() && heap->ObjectIsInBootImageSpace(obj)) {
      // Only count objects in the boot image as HPROF_HEAP_IMAGE, this leaves app image objects
      // as HPROF_HEAP_APP. b/35762934
      heap_type = kHeapIdImage;
    }
  } else {
    const auto* los = heap->GetLargeObjectsSpace();
    if (los->Contains(obj.Ptr()) && los->IsZygoteLargeObject(art::Thread::Current(), obj.Ptr())) {
      heap_type = kHeapIdZygote;
    }
  }
  return heap_type;
};

jvmtiError HeapExtensions::GetObjectHeapId(jvmtiEnv* env, jlong tag, jint* heap_id, ...) {
  if (heap_id == nullptr) {
    return ERR(NULL_POINTER);
  }

  art::Thread* self = art::Thread::Current();

  auto work = [&]() REQUIRES_SHARED(art::Locks::mutator_lock_) {
    ObjectTagTable* tag_table = ArtJvmTiEnv::AsArtJvmTiEnv(env)->object_tag_table.get();
    art::ObjPtr<art::mirror::Object> obj = tag_table->Find(tag);
    jint heap_type = GetHeapId(obj);
    if (heap_type == -1) {
      return ERR(NOT_FOUND);
    }
    *heap_id = heap_type;
    return ERR(NONE);
  };

  if (!art::Locks::mutator_lock_->IsSharedHeld(self)) {
    if (!self->IsThreadSuspensionAllowable()) {
      return ERR(INTERNAL);
    }
    art::ScopedObjectAccess soa(self);
    return work();
  } else {
    // We cannot use SOA in this case. We might be holding the lock, but may not be in the
    // runnable state (e.g., during GC).
    art::Locks::mutator_lock_->AssertSharedHeld(self);
    // TODO: Investigate why ASSERT_SHARED_CAPABILITY doesn't work.
    auto annotalysis_workaround = [&]() NO_THREAD_SAFETY_ANALYSIS {
      return work();
    };
    return annotalysis_workaround();
  }
}

static jvmtiError CopyStringAndReturn(jvmtiEnv* env, const char* in, char** out) {
  jvmtiError error;
  JvmtiUniquePtr<char[]> param_name = CopyString(env, in, &error);
  if (param_name == nullptr) {
    return error;
  }
  *out = param_name.release();
  return ERR(NONE);
}

static constexpr const char* kHeapIdDefaultName = "default";
static constexpr const char* kHeapIdImageName = "image";
static constexpr const char* kHeapIdZygoteName = "zygote";
static constexpr const char* kHeapIdAppName = "app";

jvmtiError HeapExtensions::GetHeapName(jvmtiEnv* env, jint heap_id, char** heap_name, ...) {
  switch (heap_id) {
    case kHeapIdDefault:
      return CopyStringAndReturn(env, kHeapIdDefaultName, heap_name);
    case kHeapIdImage:
      return CopyStringAndReturn(env, kHeapIdImageName, heap_name);
    case kHeapIdZygote:
      return CopyStringAndReturn(env, kHeapIdZygoteName, heap_name);
    case kHeapIdApp:
      return CopyStringAndReturn(env, kHeapIdAppName, heap_name);

    default:
      return ERR(ILLEGAL_ARGUMENT);
  }
}

jvmtiError HeapExtensions::IterateThroughHeapExt(jvmtiEnv* env,
                                                 jint heap_filter,
                                                 jclass klass,
                                                 const jvmtiHeapCallbacks* callbacks,
                                                 const void* user_data) {
  if (ArtJvmTiEnv::AsArtJvmTiEnv(env)->capabilities.can_tag_objects != 1) { \
    return ERR(MUST_POSSESS_CAPABILITY); \
  }

  // ART extension API: Also pass the heap id.
  auto ArtIterateHeap = [](art::mirror::Object* obj,
                           const jvmtiHeapCallbacks* cb_callbacks,
                           jlong class_tag,
                           jlong size,
                           jlong* tag,
                           jint length,
                           void* cb_user_data)
      REQUIRES_SHARED(art::Locks::mutator_lock_) {
    jint heap_id = GetHeapId(obj);
    using ArtExtensionAPI = jint (*)(jlong, jlong, jlong*, jint length, void*, jint);
    return reinterpret_cast<ArtExtensionAPI>(cb_callbacks->heap_iteration_callback)(
        class_tag, size, tag, length, cb_user_data, heap_id);
  };
  return DoIterateThroughHeap(ArtIterateHeap,
                              env,
                              ArtJvmTiEnv::AsArtJvmTiEnv(env)->object_tag_table.get(),
                              heap_filter,
                              klass,
                              callbacks,
                              user_data);
}

}  // namespace openjdkjvmti
