/*
 * Copyright (C) 2011 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 "class_linker.h"

#include <memory>
#include <string>
#include <string_view>

#include "android-base/strings.h"

#include "art_field-inl.h"
#include "art_method-inl.h"
#include "base/enums.h"
#include "class_linker-inl.h"
#include "class_root-inl.h"
#include "common_runtime_test.h"
#include "dex/dex_file_types.h"
#include "dex/signature-inl.h"
#include "dex/standard_dex_file.h"
#include "entrypoints/entrypoint_utils-inl.h"
#include "experimental_flags.h"
#include "gc/heap.h"
#include "handle_scope-inl.h"
#include "mirror/array-alloc-inl.h"
#include "mirror/accessible_object.h"
#include "mirror/call_site.h"
#include "mirror/class-inl.h"
#include "mirror/class_ext.h"
#include "mirror/dex_cache.h"
#include "mirror/emulated_stack_frame.h"
#include "mirror/executable.h"
#include "mirror/field.h"
#include "mirror/method_handle_impl.h"
#include "mirror/method_handles_lookup.h"
#include "mirror/method_type-inl.h"
#include "mirror/object-inl.h"
#include "mirror/object_array-alloc-inl.h"
#include "mirror/object_array-inl.h"
#include "mirror/proxy.h"
#include "mirror/reference.h"
#include "mirror/stack_frame_info.h"
#include "mirror/stack_trace_element.h"
#include "mirror/string-inl.h"
#include "mirror/var_handle.h"
#include "scoped_thread_state_change-inl.h"
#include "thread-current-inl.h"

namespace art {

class ClassLinkerTest : public CommonRuntimeTest {
 protected:
  void AssertNonExistentClass(const std::string& descriptor)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    Thread* self = Thread::Current();
    EXPECT_TRUE(class_linker_->FindSystemClass(self, descriptor.c_str()) == nullptr);
    EXPECT_TRUE(self->IsExceptionPending());
    StackHandleScope<1> hs(self);
    Handle<mirror::Object> exception = hs.NewHandle<mirror::Object>(self->GetException());
    self->ClearException();
    ObjPtr<mirror::Class> exception_class =
        class_linker_->FindSystemClass(self, "Ljava/lang/NoClassDefFoundError;");
    EXPECT_TRUE(exception->InstanceOf(exception_class));
  }

  void AssertPrimitiveClass(const std::string& descriptor)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    Thread* self = Thread::Current();
    AssertPrimitiveClass(descriptor, class_linker_->FindSystemClass(self, descriptor.c_str()));
  }

  void AssertPrimitiveClass(const std::string& descriptor, ObjPtr<mirror::Class> primitive)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    ASSERT_TRUE(primitive != nullptr);
    ASSERT_TRUE(primitive->GetClass() != nullptr);
    ASSERT_OBJ_PTR_EQ(primitive->GetClass(), primitive->GetClass()->GetClass());
    EXPECT_TRUE(primitive->GetClass()->GetSuperClass() != nullptr);
    std::string temp;
    ASSERT_STREQ(descriptor.c_str(), primitive->GetDescriptor(&temp));
    EXPECT_TRUE(primitive->GetSuperClass() == nullptr);
    EXPECT_FALSE(primitive->HasSuperClass());
    EXPECT_TRUE(primitive->GetClassLoader() == nullptr);
    EXPECT_EQ(ClassStatus::kVisiblyInitialized, primitive->GetStatus());
    EXPECT_FALSE(primitive->IsErroneous());
    EXPECT_TRUE(primitive->IsLoaded());
    EXPECT_TRUE(primitive->IsResolved());
    EXPECT_FALSE(primitive->IsErroneousResolved());
    EXPECT_TRUE(primitive->IsVerified());
    EXPECT_TRUE(primitive->IsInitialized());
    EXPECT_FALSE(primitive->IsArrayInstance());
    EXPECT_FALSE(primitive->IsArrayClass());
    EXPECT_TRUE(primitive->GetComponentType() == nullptr);
    EXPECT_FALSE(primitive->IsInterface());
    EXPECT_TRUE(primitive->IsPublic());
    EXPECT_TRUE(primitive->IsFinal());
    EXPECT_TRUE(primitive->IsPrimitive());
    EXPECT_FALSE(primitive->IsSynthetic());
    EXPECT_EQ(0U, primitive->NumDirectMethods());
    EXPECT_EQ(0U, primitive->NumVirtualMethods());
    EXPECT_EQ(0U, primitive->NumInstanceFields());
    EXPECT_EQ(0U, primitive->NumStaticFields());
    EXPECT_EQ(0U, primitive->NumDirectInterfaces());
    EXPECT_FALSE(primitive->HasVTable());
    EXPECT_EQ(0, primitive->GetIfTableCount());
    EXPECT_TRUE(primitive->GetIfTable() != nullptr);
    EXPECT_EQ(primitive->GetIfTable()->Count(), 0u);
    EXPECT_EQ(kAccPublic | kAccFinal | kAccAbstract, primitive->GetAccessFlags());
  }

  void AssertObjectClass(ObjPtr<mirror::Class> JavaLangObject)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    ASSERT_TRUE(JavaLangObject != nullptr);
    ASSERT_TRUE(JavaLangObject->GetClass() != nullptr);
    ASSERT_OBJ_PTR_EQ(JavaLangObject->GetClass(), JavaLangObject->GetClass()->GetClass());
    EXPECT_OBJ_PTR_EQ(JavaLangObject, JavaLangObject->GetClass()->GetSuperClass());
    std::string temp;
    ASSERT_STREQ(JavaLangObject->GetDescriptor(&temp), "Ljava/lang/Object;");
    EXPECT_TRUE(JavaLangObject->GetSuperClass() == nullptr);
    EXPECT_FALSE(JavaLangObject->HasSuperClass());
    EXPECT_TRUE(JavaLangObject->GetClassLoader() == nullptr);
    {
      Thread* self = Thread::Current();
      StackHandleScope<1> hs(self);
      HandleWrapperObjPtr<mirror::Class> h(hs.NewHandleWrapper(&JavaLangObject));
      ScopedThreadSuspension sts(self, ThreadState::kNative);
      class_linker_->MakeInitializedClassesVisiblyInitialized(self, /*wait=*/ true);
      // HandleWrapperObjPtr restores JavaLangObject here after becoming runnable again.
    }
    EXPECT_EQ(ClassStatus::kVisiblyInitialized, JavaLangObject->GetStatus());
    EXPECT_FALSE(JavaLangObject->IsErroneous());
    EXPECT_TRUE(JavaLangObject->IsLoaded());
    EXPECT_TRUE(JavaLangObject->IsResolved());
    EXPECT_FALSE(JavaLangObject->IsErroneousResolved());
    EXPECT_TRUE(JavaLangObject->IsVerified());
    EXPECT_TRUE(JavaLangObject->IsInitialized());
    EXPECT_FALSE(JavaLangObject->IsArrayInstance());
    EXPECT_FALSE(JavaLangObject->IsArrayClass());
    EXPECT_TRUE(JavaLangObject->GetComponentType() == nullptr);
    EXPECT_FALSE(JavaLangObject->IsInterface());
    EXPECT_TRUE(JavaLangObject->IsPublic());
    EXPECT_FALSE(JavaLangObject->IsFinal());
    EXPECT_FALSE(JavaLangObject->IsPrimitive());
    EXPECT_FALSE(JavaLangObject->IsSynthetic());
    EXPECT_EQ(4U, JavaLangObject->NumDirectMethods());
    EXPECT_EQ(11U, JavaLangObject->NumVirtualMethods());
    EXPECT_EQ(2U, JavaLangObject->NumInstanceFields());
    EXPECT_STREQ(JavaLangObject->GetInstanceField(0)->GetName(),
                 "shadow$_klass_");
    EXPECT_STREQ(JavaLangObject->GetInstanceField(1)->GetName(),
                 "shadow$_monitor_");

    EXPECT_EQ(0U, JavaLangObject->NumStaticFields());
    EXPECT_EQ(0U, JavaLangObject->NumDirectInterfaces());

    PointerSize pointer_size = class_linker_->GetImagePointerSize();
    ArtMethod* unimplemented = runtime_->GetImtUnimplementedMethod();
    ImTable* imt = JavaLangObject->GetImt(pointer_size);
    ASSERT_NE(nullptr, imt);
    for (size_t i = 0; i < ImTable::kSize; ++i) {
      ASSERT_EQ(unimplemented, imt->Get(i, pointer_size));
    }
  }

  void AssertArrayClass(const std::string& array_descriptor,
                        const std::string& component_type,
                        ObjPtr<mirror::ClassLoader> class_loader)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    Thread* self = Thread::Current();
    StackHandleScope<2> hs(self);
    Handle<mirror::ClassLoader> loader(hs.NewHandle(class_loader));
    Handle<mirror::Class> array(
        hs.NewHandle(class_linker_->FindClass(self, array_descriptor.c_str(), loader)));
    std::string temp;
    EXPECT_STREQ(component_type.c_str(), array->GetComponentType()->GetDescriptor(&temp));
    EXPECT_OBJ_PTR_EQ(loader.Get(), array->GetClassLoader());
    EXPECT_EQ(kAccFinal | kAccAbstract, (array->GetAccessFlags() & (kAccFinal | kAccAbstract)));
    AssertArrayClass(array_descriptor, array);
  }

  void AssertArrayClass(const std::string& array_descriptor, Handle<mirror::Class> array)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    ASSERT_TRUE(array != nullptr);
    ASSERT_TRUE(array->GetClass() != nullptr);
    ASSERT_OBJ_PTR_EQ(array->GetClass(), array->GetClass()->GetClass());
    EXPECT_TRUE(array->GetClass()->GetSuperClass() != nullptr);
    std::string temp;
    ASSERT_STREQ(array_descriptor.c_str(), array->GetDescriptor(&temp));
    EXPECT_TRUE(array->GetSuperClass() != nullptr);
    Thread* self = Thread::Current();
    EXPECT_OBJ_PTR_EQ(class_linker_->FindSystemClass(self, "Ljava/lang/Object;"),
                      array->GetSuperClass());
    EXPECT_TRUE(array->HasSuperClass());
    ASSERT_TRUE(array->GetComponentType() != nullptr);
    ASSERT_GT(strlen(array->GetComponentType()->GetDescriptor(&temp)), 0U);
    EXPECT_EQ(ClassStatus::kVisiblyInitialized, array->GetStatus());
    EXPECT_FALSE(array->IsErroneous());
    EXPECT_TRUE(array->IsLoaded());
    EXPECT_TRUE(array->IsResolved());
    EXPECT_FALSE(array->IsErroneousResolved());
    EXPECT_TRUE(array->IsVerified());
    EXPECT_TRUE(array->IsInitialized());
    EXPECT_FALSE(array->IsArrayInstance());
    EXPECT_TRUE(array->IsArrayClass());
    EXPECT_FALSE(array->IsInterface());
    EXPECT_EQ(array->GetComponentType()->IsPublic(), array->IsPublic());
    EXPECT_TRUE(array->IsFinal());
    EXPECT_FALSE(array->IsPrimitive());
    EXPECT_FALSE(array->IsSynthetic());
    EXPECT_EQ(0U, array->NumDirectMethods());
    EXPECT_EQ(0U, array->NumVirtualMethods());
    EXPECT_EQ(0U, array->NumInstanceFields());
    EXPECT_EQ(0U, array->NumStaticFields());
    EXPECT_EQ(2U, array->NumDirectInterfaces());
    EXPECT_TRUE(array->ShouldHaveImt());
    EXPECT_TRUE(array->ShouldHaveEmbeddedVTable());
    EXPECT_EQ(2, array->GetIfTableCount());
    ASSERT_TRUE(array->GetIfTable() != nullptr);
    ObjPtr<mirror::Class> direct_interface0 = array->GetDirectInterface(0);
    EXPECT_TRUE(direct_interface0 != nullptr);
    EXPECT_STREQ(direct_interface0->GetDescriptor(&temp), "Ljava/lang/Cloneable;");
    ObjPtr<mirror::Class> direct_interface1 = array->GetDirectInterface(1);
    EXPECT_STREQ(direct_interface1->GetDescriptor(&temp), "Ljava/io/Serializable;");
    EXPECT_OBJ_PTR_EQ(class_linker_->FindArrayClass(self, array->GetComponentType()), array.Get());

    PointerSize pointer_size = class_linker_->GetImagePointerSize();
    ObjPtr<mirror::Class> JavaLangObject =
        class_linker_->FindSystemClass(self, "Ljava/lang/Object;");
    ImTable* JavaLangObject_imt = JavaLangObject->GetImt(pointer_size);
    // IMT of a array class should be shared with the IMT of the java.lag.Object
    ASSERT_EQ(JavaLangObject_imt, array->GetImt(pointer_size));
  }

  void AssertMethod(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_) {
    EXPECT_TRUE(method != nullptr);
    EXPECT_TRUE(method->GetDeclaringClass() != nullptr);
    EXPECT_TRUE(method->GetName() != nullptr);
    EXPECT_TRUE(method->GetSignature() != Signature::NoSignature());
  }

  void AssertField(ObjPtr<mirror::Class> klass, ArtField* field)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    EXPECT_TRUE(field != nullptr);
    EXPECT_OBJ_PTR_EQ(klass, field->GetDeclaringClass());
    EXPECT_TRUE(field->GetName() != nullptr);
    EXPECT_TRUE(field->ResolveType() != nullptr);
  }

  void AssertClass(const std::string& descriptor, Handle<mirror::Class> klass)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    std::string temp;
    EXPECT_STREQ(descriptor.c_str(), klass->GetDescriptor(&temp));
    if (descriptor == "Ljava/lang/Object;") {
      EXPECT_FALSE(klass->HasSuperClass());
    } else {
      EXPECT_TRUE(klass->HasSuperClass());
      EXPECT_TRUE(klass->GetSuperClass() != nullptr);
    }
    EXPECT_TRUE(klass->GetClass() != nullptr);
    EXPECT_OBJ_PTR_EQ(klass->GetClass(), klass->GetClass()->GetClass());
    EXPECT_TRUE(klass->GetDexCache() != nullptr);
    EXPECT_TRUE(klass->IsLoaded());
    EXPECT_TRUE(klass->IsResolved());
    EXPECT_FALSE(klass->IsErroneousResolved());
    EXPECT_FALSE(klass->IsErroneous());
    EXPECT_FALSE(klass->IsArrayClass());
    EXPECT_TRUE(klass->GetComponentType() == nullptr);
    EXPECT_TRUE(klass->IsInSamePackage(klass.Get()));
    std::string temp2;
    EXPECT_TRUE(mirror::Class::IsInSamePackage(klass->GetDescriptor(&temp),
                                               klass->GetDescriptor(&temp2)));
    if (klass->IsInterface()) {
      EXPECT_TRUE(klass->IsAbstract());
      // Check that all methods are direct and either static (<clinit> or a regular static method),
      // or private.
      for (ArtMethod& m : klass->GetDirectMethods(kRuntimePointerSize)) {
        EXPECT_TRUE(m.IsStatic() || m.IsPrivate());
        EXPECT_TRUE(m.IsDirect());
      }
    } else {
      if (!klass->IsSynthetic()) {
        EXPECT_NE(0U, klass->NumDirectMethods());
      }
    }
    EXPECT_EQ(klass->IsInterface(), !klass->HasVTable());
    ObjPtr<mirror::IfTable> iftable = klass->GetIfTable();
    for (int i = 0; i < klass->GetIfTableCount(); i++) {
      ObjPtr<mirror::Class> interface = iftable->GetInterface(i);
      ASSERT_TRUE(interface != nullptr);
      if (klass->IsInterface()) {
        EXPECT_EQ(0U, iftable->GetMethodArrayCount(i));
      } else {
        EXPECT_EQ(interface->NumDeclaredVirtualMethods(), iftable->GetMethodArrayCount(i));
      }
    }
    if (klass->IsAbstract()) {
      EXPECT_FALSE(klass->IsFinal());
    } else {
      EXPECT_FALSE(klass->IsAnnotation());
    }
    if (klass->IsFinal()) {
      EXPECT_FALSE(klass->IsAbstract());
      EXPECT_FALSE(klass->IsAnnotation());
    }
    if (klass->IsAnnotation()) {
      EXPECT_FALSE(klass->IsFinal());
      EXPECT_TRUE(klass->IsAbstract());
    }

    EXPECT_FALSE(klass->IsPrimitive());
    EXPECT_TRUE(klass->CanAccess(klass.Get()));

    for (ArtMethod& method : klass->GetDirectMethods(kRuntimePointerSize)) {
      AssertMethod(&method);
      EXPECT_TRUE(method.IsDirect());
      EXPECT_OBJ_PTR_EQ(klass.Get(), method.GetDeclaringClass());
    }

    for (ArtMethod& method : klass->GetDeclaredVirtualMethods(kRuntimePointerSize)) {
      AssertMethod(&method);
      EXPECT_FALSE(method.IsDirect());
      EXPECT_OBJ_PTR_EQ(klass.Get(), method.GetDeclaringClass());
    }

    for (ArtMethod& method : klass->GetCopiedMethods(kRuntimePointerSize)) {
      AssertMethod(&method);
      EXPECT_FALSE(method.IsDirect());
      EXPECT_TRUE(method.IsCopied());
      EXPECT_TRUE(method.GetDeclaringClass()->IsInterface())
          << "declaring class: " << method.GetDeclaringClass()->PrettyClass();
      EXPECT_TRUE(method.GetDeclaringClass()->IsAssignableFrom(klass.Get()))
          << "declaring class: " << method.GetDeclaringClass()->PrettyClass();
    }

    for (size_t i = 0; i < klass->NumInstanceFields(); i++) {
      ArtField* field = klass->GetInstanceField(i);
      AssertField(klass.Get(), field);
      EXPECT_FALSE(field->IsStatic());
    }

    for (size_t i = 0; i < klass->NumStaticFields(); i++) {
      ArtField* field = klass->GetStaticField(i);
      AssertField(klass.Get(), field);
      EXPECT_TRUE(field->IsStatic());
    }

    // Confirm that all instances field offsets are packed together at the start.
    EXPECT_GE(klass->NumInstanceFields(), klass->NumReferenceInstanceFields());
    MemberOffset start_ref_offset = klass->GetFirstReferenceInstanceFieldOffset();
    MemberOffset end_ref_offset(start_ref_offset.Uint32Value() +
                                klass->NumReferenceInstanceFields() *
                                    sizeof(mirror::HeapReference<mirror::Object>));
    MemberOffset current_ref_offset = start_ref_offset;
    for (size_t i = 0; i < klass->NumInstanceFields(); i++) {
      ArtField* field = klass->GetInstanceField(i);
      ObjPtr<mirror::Class> field_type = field->ResolveType();
      ASSERT_TRUE(field_type != nullptr);
      if (!field->IsPrimitiveType()) {
        ASSERT_TRUE(!field_type->IsPrimitive());
        ASSERT_EQ(current_ref_offset.Uint32Value(), field->GetOffset().Uint32Value());
        if (current_ref_offset.Uint32Value() == end_ref_offset.Uint32Value()) {
          // While Reference.referent is not primitive, the ClassLinker
          // treats it as such so that the garbage collector won't scan it.
          EXPECT_EQ(field->PrettyField(), "java.lang.Object java.lang.ref.Reference.referent");
        } else {
          current_ref_offset = MemberOffset(current_ref_offset.Uint32Value() +
                                            sizeof(mirror::HeapReference<mirror::Object>));
        }
      } else {
        if (field->GetOffset().Uint32Value() < end_ref_offset.Uint32Value()) {
          // Shuffled before references.
          ASSERT_LT(field->GetOffset().Uint32Value(), start_ref_offset.Uint32Value());
          CHECK(!IsAligned<4>(field->GetOffset().Uint32Value()));
        }
      }
    }
    ASSERT_EQ(end_ref_offset.Uint32Value(), current_ref_offset.Uint32Value());

    uint32_t total_num_reference_instance_fields = 0;
    ObjPtr<mirror::Class> k = klass.Get();
    while (k != nullptr) {
      total_num_reference_instance_fields += k->NumReferenceInstanceFields();
      k = k->GetSuperClass();
    }
    EXPECT_GE(total_num_reference_instance_fields, 1U);  // Should always have Object's class.
    if (klass->GetReferenceInstanceOffsets() != mirror::Class::kClassWalkSuper) {
      // The reference instance offsets have a bit set for each reference offset.
      // +1 for Object's class.
      EXPECT_EQ(static_cast<uint32_t>(POPCOUNT(klass->GetReferenceInstanceOffsets())) + 1,
                total_num_reference_instance_fields);
    }
  }

  void AssertDexFileClass(ObjPtr<mirror::ClassLoader> class_loader, const std::string& descriptor)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    ASSERT_FALSE(descriptor.empty());
    Thread* self = Thread::Current();
    StackHandleScope<1> hs(self);
    Handle<mirror::Class> klass(
        hs.NewHandle(class_linker_->FindSystemClass(self, descriptor.c_str())));
    ASSERT_TRUE(klass != nullptr);
    std::string temp;
    EXPECT_STREQ(descriptor.c_str(), klass->GetDescriptor(&temp));
    EXPECT_OBJ_PTR_EQ(class_loader, klass->GetClassLoader());
    if (klass->IsPrimitive()) {
      AssertPrimitiveClass(descriptor, klass.Get());
    } else if (klass->IsArrayClass()) {
      AssertArrayClass(descriptor, klass);
    } else {
      AssertClass(descriptor, klass);
    }
  }

  void AssertDexFile(const DexFile& dex, ObjPtr<mirror::ClassLoader> class_loader)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    // Verify all the classes defined in this file
    for (size_t i = 0; i < dex.NumClassDefs(); i++) {
      const dex::ClassDef& class_def = dex.GetClassDef(i);
      const char* descriptor = dex.GetClassDescriptor(class_def);
      AssertDexFileClass(class_loader, descriptor);
    }
    // Verify all the types referenced by this file
    for (size_t i = 0; i < dex.NumTypeIds(); i++) {
      const dex::TypeId& type_id = dex.GetTypeId(dex::TypeIndex(i));
      const char* descriptor = dex.GetTypeDescriptor(type_id);
      AssertDexFileClass(class_loader, descriptor);
    }
    TestRootVisitor visitor;
    class_linker_->VisitRoots(&visitor, kVisitRootFlagAllRoots);
  }

  class TestRootVisitor : public SingleRootVisitor {
   public:
    void VisitRoot(mirror::Object* root, [[maybe_unused]] const RootInfo& info) override {
      EXPECT_TRUE(root != nullptr);
    }
  };
};

class ClassLinkerMethodHandlesTest : public ClassLinkerTest {
 protected:
  void SetUpRuntimeOptions(RuntimeOptions* options) override {
    CommonRuntimeTest::SetUpRuntimeOptions(options);
  }
};

struct CheckOffset {
  size_t cpp_offset;
  const char* java_name;
  CheckOffset(size_t c, const char* j) : cpp_offset(c), java_name(j) {}
};

template <typename T>
struct CheckOffsets {
  CheckOffsets(bool is_static_in, const char* class_descriptor_in)
      : is_static(is_static_in), class_descriptor(class_descriptor_in) {}
  bool is_static;
  std::string class_descriptor;
  std::vector<CheckOffset> offsets;

  bool Check() REQUIRES_SHARED(Locks::mutator_lock_) {
    Thread* self = Thread::Current();
    ObjPtr<mirror::Class> klass =
        Runtime::Current()->GetClassLinker()->FindSystemClass(self, class_descriptor.c_str());
    CHECK(klass != nullptr) << class_descriptor;
    CHECK(klass->IsMirrored()) << class_descriptor;

    bool error = false;

    // Classes have a different size due to padding field. Strings are variable length.
    if (!klass->IsClassClass() && !klass->IsStringClass() && !is_static) {
      // The RoundUp is required for some mirror classes that have a gap at the end,
      // such as AccessibleObject, ByteArrayViewVarHandle and ByteBufferViewVarHandle.
      // For example, the AccessibleObject has size 9 according to the class linker.
      // However, the C++ sizeof(AccessibleObject) is 12 bytes due to alignment, even
      // though members in C++ subclasses are actually starting at offset 9.
      //
      // TODO: We could define a subclass with a `uint8_t` member and check its offset instead.
      static constexpr size_t kPackAlignment = 4;
      size_t expected_size = RoundUp(klass->GetObjectSize(), kPackAlignment);
      if (sizeof(T) != expected_size) {
        LOG(ERROR) << "Class size mismatch:"
           << " class=" << class_descriptor
           << " Java=" << expected_size
           << " C++=" << sizeof(T);
        error = true;
      }
    }

    size_t num_fields = is_static ? klass->NumStaticFields() : klass->NumInstanceFields();
    if (offsets.size() != num_fields) {
      LOG(ERROR) << "Field count mismatch:"
         << " class=" << class_descriptor
         << " Java=" << num_fields
         << " C++=" << offsets.size();
      error = true;
    }

    for (size_t i = 0; i < offsets.size(); i++) {
      ArtField* field = is_static ? klass->GetStaticField(i) : klass->GetInstanceField(i);
      std::string_view field_name(field->GetName());
      if (field_name != offsets[i].java_name) {
        error = true;
      }
    }
    if (error) {
      for (size_t i = 0; i < offsets.size(); i++) {
        CheckOffset& offset = offsets[i];
        ArtField* field = is_static ? klass->GetStaticField(i) : klass->GetInstanceField(i);
        std::string_view field_name(field->GetName());
        if (field_name != offsets[i].java_name) {
          LOG(ERROR) << "JAVA FIELD ORDER MISMATCH NEXT LINE:";
        }
        LOG(ERROR) << "Java field order:"
           << " i=" << i << " class=" << class_descriptor
           << " Java=" << field_name
           << " CheckOffsets=" << offset.java_name;
      }
    }

    for (size_t i = 0; i < offsets.size(); i++) {
      CheckOffset& offset = offsets[i];
      ArtField* field = is_static ? klass->GetStaticField(i) : klass->GetInstanceField(i);
      if (field->GetOffset().Uint32Value() != offset.cpp_offset) {
        error = true;
      }
    }
    if (error) {
      for (size_t i = 0; i < offsets.size(); i++) {
        CheckOffset& offset = offsets[i];
        ArtField* field = is_static ? klass->GetStaticField(i) : klass->GetInstanceField(i);
        if (field->GetOffset().Uint32Value() != offset.cpp_offset) {
          LOG(ERROR) << "OFFSET MISMATCH NEXT LINE:";
        }
        LOG(ERROR) << "Offset: class=" << class_descriptor << " field=" << offset.java_name
           << " Java=" << field->GetOffset().Uint32Value() << " C++=" << offset.cpp_offset;
      }
    }

    return !error;
  };

  void addOffset(size_t offset, const char* name) {
    offsets.push_back(CheckOffset(offset, name));
  }

 private:
  DISALLOW_IMPLICIT_CONSTRUCTORS(CheckOffsets);
};

// Note that ClassLinkerTest.ValidateFieldOrderOfJavaCppUnionClasses
// is first since if it is failing, others are unlikely to succeed.

struct ObjectOffsets : public CheckOffsets<mirror::Object> {
  ObjectOffsets() : CheckOffsets<mirror::Object>(false, "Ljava/lang/Object;") {
    addOffset(OFFSETOF_MEMBER(mirror::Object, klass_), "shadow$_klass_");
    addOffset(OFFSETOF_MEMBER(mirror::Object, monitor_), "shadow$_monitor_");
  }
};

struct ClassOffsets : public CheckOffsets<mirror::Class> {
  ClassOffsets() : CheckOffsets<mirror::Class>(false, "Ljava/lang/Class;") {
    addOffset(OFFSETOF_MEMBER(mirror::Class, access_flags_), "accessFlags");
    addOffset(OFFSETOF_MEMBER(mirror::Class, class_flags_), "classFlags");
    addOffset(OFFSETOF_MEMBER(mirror::Class, class_loader_), "classLoader");
    addOffset(OFFSETOF_MEMBER(mirror::Class, class_size_), "classSize");
    addOffset(OFFSETOF_MEMBER(mirror::Class, clinit_thread_id_), "clinitThreadId");
    addOffset(OFFSETOF_MEMBER(mirror::Class, component_type_), "componentType");
    addOffset(OFFSETOF_MEMBER(mirror::Class, copied_methods_offset_), "copiedMethodsOffset");
    addOffset(OFFSETOF_MEMBER(mirror::Class, dex_cache_), "dexCache");
    addOffset(OFFSETOF_MEMBER(mirror::Class, dex_class_def_idx_), "dexClassDefIndex");
    addOffset(OFFSETOF_MEMBER(mirror::Class, dex_type_idx_), "dexTypeIndex");
    addOffset(OFFSETOF_MEMBER(mirror::Class, ext_data_), "extData");
    addOffset(OFFSETOF_MEMBER(mirror::Class, ifields_), "iFields");
    addOffset(OFFSETOF_MEMBER(mirror::Class, iftable_), "ifTable");
    addOffset(OFFSETOF_MEMBER(mirror::Class, methods_), "methods");
    addOffset(OFFSETOF_MEMBER(mirror::Class, name_), "name");
    addOffset(OFFSETOF_MEMBER(mirror::Class, num_reference_instance_fields_),
              "numReferenceInstanceFields");
    addOffset(OFFSETOF_MEMBER(mirror::Class, num_reference_static_fields_),
              "numReferenceStaticFields");
    addOffset(OFFSETOF_MEMBER(mirror::Class, object_size_), "objectSize");
    addOffset(OFFSETOF_MEMBER(mirror::Class, object_size_alloc_fast_path_),
              "objectSizeAllocFastPath");
    addOffset(OFFSETOF_MEMBER(mirror::Class, primitive_type_), "primitiveType");
    addOffset(OFFSETOF_MEMBER(mirror::Class, reference_instance_offsets_),
              "referenceInstanceOffsets");
    addOffset(OFFSETOF_MEMBER(mirror::Class, sfields_), "sFields");
    addOffset(OFFSETOF_MEMBER(mirror::Class, status_), "status");
    addOffset(OFFSETOF_MEMBER(mirror::Class, super_class_), "superClass");
    addOffset(OFFSETOF_MEMBER(mirror::Class, virtual_methods_offset_), "virtualMethodsOffset");
    addOffset(OFFSETOF_MEMBER(mirror::Class, vtable_), "vtable");
  }
};

struct ClassExtOffsets : public CheckOffsets<mirror::ClassExt> {
  ClassExtOffsets() : CheckOffsets<mirror::ClassExt>(false, "Ldalvik/system/ClassExt;") {
    addOffset(OFFSETOF_MEMBER(mirror::ClassExt, class_value_map_), "classValueMap");
    addOffset(OFFSETOF_MEMBER(mirror::ClassExt, erroneous_state_error_), "erroneousStateError");
    addOffset(OFFSETOF_MEMBER(mirror::ClassExt, instance_jfield_ids_), "instanceJfieldIDs");
    addOffset(OFFSETOF_MEMBER(mirror::ClassExt, jmethod_ids_), "jmethodIDs");
    addOffset(OFFSETOF_MEMBER(mirror::ClassExt, obsolete_class_), "obsoleteClass");
    addOffset(OFFSETOF_MEMBER(mirror::ClassExt, obsolete_dex_caches_), "obsoleteDexCaches");
    addOffset(OFFSETOF_MEMBER(mirror::ClassExt, obsolete_methods_), "obsoleteMethods");
    addOffset(OFFSETOF_MEMBER(mirror::ClassExt, original_dex_file_), "originalDexFile");
    addOffset(OFFSETOF_MEMBER(mirror::ClassExt, pre_redefine_class_def_index_),
              "preRedefineClassDefIndex");
    addOffset(OFFSETOF_MEMBER(mirror::ClassExt, pre_redefine_dex_file_ptr_),
              "preRedefineDexFilePtr");
    addOffset(OFFSETOF_MEMBER(mirror::ClassExt, static_jfield_ids_), "staticJfieldIDs");
  }
};

struct StringOffsets : public CheckOffsets<mirror::String> {
  StringOffsets() : CheckOffsets<mirror::String>(false, "Ljava/lang/String;") {
    addOffset(OFFSETOF_MEMBER(mirror::String, count_), "count");
    addOffset(OFFSETOF_MEMBER(mirror::String, hash_code_), "hash");
  }
};

struct ThrowableOffsets : public CheckOffsets<mirror::Throwable> {
  ThrowableOffsets() : CheckOffsets<mirror::Throwable>(false, "Ljava/lang/Throwable;") {
    addOffset(OFFSETOF_MEMBER(mirror::Throwable, backtrace_), "backtrace");
    addOffset(OFFSETOF_MEMBER(mirror::Throwable, cause_), "cause");
    addOffset(OFFSETOF_MEMBER(mirror::Throwable, detail_message_), "detailMessage");
    addOffset(OFFSETOF_MEMBER(mirror::Throwable, stack_trace_), "stackTrace");
    addOffset(OFFSETOF_MEMBER(mirror::Throwable, suppressed_exceptions_), "suppressedExceptions");
  }
};

struct StackTraceElementOffsets : public CheckOffsets<mirror::StackTraceElement> {
  StackTraceElementOffsets() : CheckOffsets<mirror::StackTraceElement>(
      false, "Ljava/lang/StackTraceElement;") {
    addOffset(OFFSETOF_MEMBER(mirror::StackTraceElement, declaring_class_), "declaringClass");
    addOffset(OFFSETOF_MEMBER(mirror::StackTraceElement, file_name_), "fileName");
    addOffset(OFFSETOF_MEMBER(mirror::StackTraceElement, line_number_), "lineNumber");
    addOffset(OFFSETOF_MEMBER(mirror::StackTraceElement, method_name_), "methodName");
  }
};

struct StackFrameInfoOffsets : public CheckOffsets<mirror::StackFrameInfo> {
  StackFrameInfoOffsets() : CheckOffsets<mirror::StackFrameInfo>(
      false, "Ljava/lang/StackFrameInfo;") {
    addOffset(OFFSETOF_MEMBER(mirror::StackFrameInfo, bci_), "bci");
    addOffset(OFFSETOF_MEMBER(mirror::StackFrameInfo, declaring_class_), "declaringClass");
    addOffset(OFFSETOF_MEMBER(mirror::StackFrameInfo, file_name_), "fileName");
    addOffset(OFFSETOF_MEMBER(mirror::StackFrameInfo, line_number_), "lineNumber");
    addOffset(OFFSETOF_MEMBER(mirror::StackFrameInfo, method_name_), "methodName");
    addOffset(OFFSETOF_MEMBER(mirror::StackFrameInfo, method_type_), "methodType");
    addOffset(OFFSETOF_MEMBER(mirror::StackFrameInfo, retain_class_ref_), "retainClassRef");
    addOffset(OFFSETOF_MEMBER(mirror::StackFrameInfo, ste_), "ste");
  }
};

struct ClassLoaderOffsets : public CheckOffsets<mirror::ClassLoader> {
  ClassLoaderOffsets() : CheckOffsets<mirror::ClassLoader>(false, "Ljava/lang/ClassLoader;") {
    addOffset(OFFSETOF_MEMBER(mirror::ClassLoader, allocator_), "allocator");
    addOffset(OFFSETOF_MEMBER(mirror::ClassLoader, class_table_), "classTable");
    addOffset(OFFSETOF_MEMBER(mirror::ClassLoader, packages_), "packages");
    addOffset(OFFSETOF_MEMBER(mirror::ClassLoader, parent_), "parent");
    addOffset(OFFSETOF_MEMBER(mirror::ClassLoader, proxyCache_), "proxyCache");
  }
};

struct ProxyOffsets : public CheckOffsets<mirror::Proxy> {
  ProxyOffsets() : CheckOffsets<mirror::Proxy>(false, "Ljava/lang/reflect/Proxy;") {
    addOffset(OFFSETOF_MEMBER(mirror::Proxy, h_), "h");
  }
};

struct DexCacheOffsets : public CheckOffsets<mirror::DexCache> {
  DexCacheOffsets() : CheckOffsets<mirror::DexCache>(false, "Ljava/lang/DexCache;") {
    addOffset(OFFSETOF_MEMBER(mirror::DexCache, class_loader_), "classLoader");
    addOffset(OFFSETOF_MEMBER(mirror::DexCache, dex_file_), "dexFile");
    addOffset(OFFSETOF_MEMBER(mirror::DexCache, location_), "location");
    addOffset(OFFSETOF_MEMBER(mirror::DexCache, resolved_call_sites_), "resolvedCallSites");
    addOffset(OFFSETOF_MEMBER(mirror::DexCache, resolved_fields_), "resolvedFields");
    addOffset(OFFSETOF_MEMBER(mirror::DexCache, resolved_fields_array_), "resolvedFieldsArray");
    addOffset(OFFSETOF_MEMBER(mirror::DexCache, resolved_method_types_), "resolvedMethodTypes");
    addOffset(OFFSETOF_MEMBER(mirror::DexCache, resolved_method_types_array_),
              "resolvedMethodTypesArray");
    addOffset(OFFSETOF_MEMBER(mirror::DexCache, resolved_methods_), "resolvedMethods");
    addOffset(OFFSETOF_MEMBER(mirror::DexCache, resolved_methods_array_), "resolvedMethodsArray");
    addOffset(OFFSETOF_MEMBER(mirror::DexCache, resolved_types_), "resolvedTypes");
    addOffset(OFFSETOF_MEMBER(mirror::DexCache, resolved_types_array_), "resolvedTypesArray");
    addOffset(OFFSETOF_MEMBER(mirror::DexCache, strings_), "strings");
    addOffset(OFFSETOF_MEMBER(mirror::DexCache, strings_array_), "stringsArray");
  }
};

struct ReferenceOffsets : public CheckOffsets<mirror::Reference> {
  ReferenceOffsets() : CheckOffsets<mirror::Reference>(false, "Ljava/lang/ref/Reference;") {
    addOffset(OFFSETOF_MEMBER(mirror::Reference, pending_next_), "pendingNext");
    addOffset(OFFSETOF_MEMBER(mirror::Reference, queue_), "queue");
    addOffset(OFFSETOF_MEMBER(mirror::Reference, queue_next_), "queueNext");
    addOffset(OFFSETOF_MEMBER(mirror::Reference, referent_), "referent");
  }
};

struct FinalizerReferenceOffsets : public CheckOffsets<mirror::FinalizerReference> {
  FinalizerReferenceOffsets() : CheckOffsets<mirror::FinalizerReference>(
      false, "Ljava/lang/ref/FinalizerReference;") {
    addOffset(OFFSETOF_MEMBER(mirror::FinalizerReference, next_), "next");
    addOffset(OFFSETOF_MEMBER(mirror::FinalizerReference, prev_), "prev");
    addOffset(OFFSETOF_MEMBER(mirror::FinalizerReference, zombie_), "zombie");
  }
};

struct AccessibleObjectOffsets : public CheckOffsets<mirror::AccessibleObject> {
  AccessibleObjectOffsets() : CheckOffsets<mirror::AccessibleObject>(
      false, "Ljava/lang/reflect/AccessibleObject;") {
    addOffset(mirror::AccessibleObject::FlagOffset().Uint32Value(), "override");
  }
};

struct FieldOffsets : public CheckOffsets<mirror::Field> {
  FieldOffsets() : CheckOffsets<mirror::Field>(false, "Ljava/lang/reflect/Field;") {
    addOffset(OFFSETOF_MEMBER(mirror::Field, access_flags_), "accessFlags");
    addOffset(OFFSETOF_MEMBER(mirror::Field, art_field_index_), "artFieldIndex");
    addOffset(OFFSETOF_MEMBER(mirror::Field, declaring_class_), "declaringClass");
    addOffset(OFFSETOF_MEMBER(mirror::Field, offset_), "offset");
    addOffset(OFFSETOF_MEMBER(mirror::Field, type_), "type");
  }
};

struct ExecutableOffsets : public CheckOffsets<mirror::Executable> {
  ExecutableOffsets() : CheckOffsets<mirror::Executable>(
      false, "Ljava/lang/reflect/Executable;") {
    addOffset(OFFSETOF_MEMBER(mirror::Executable, access_flags_), "accessFlags");
    addOffset(OFFSETOF_MEMBER(mirror::Executable, art_method_), "artMethod");
    addOffset(OFFSETOF_MEMBER(mirror::Executable, declaring_class_), "declaringClass");
    addOffset(OFFSETOF_MEMBER(mirror::Executable, declaring_class_of_overridden_method_),
              "declaringClassOfOverriddenMethod");
    addOffset(OFFSETOF_MEMBER(mirror::Executable, dex_method_index_), "dexMethodIndex");
    addOffset(OFFSETOF_MEMBER(mirror::Executable, has_real_parameter_data_),
              "hasRealParameterData");
    addOffset(OFFSETOF_MEMBER(mirror::Executable, parameters_), "parameters");
  }
};

struct MethodTypeOffsets : public CheckOffsets<mirror::MethodType> {
  MethodTypeOffsets() : CheckOffsets<mirror::MethodType>(
      false, "Ljava/lang/invoke/MethodType;") {
    addOffset(OFFSETOF_MEMBER(mirror::MethodType, form_), "form");
    addOffset(OFFSETOF_MEMBER(mirror::MethodType, method_descriptor_), "methodDescriptor");
    addOffset(OFFSETOF_MEMBER(mirror::MethodType, p_types_), "ptypes");
    addOffset(OFFSETOF_MEMBER(mirror::MethodType, r_type_), "rtype");
    addOffset(OFFSETOF_MEMBER(mirror::MethodType, wrap_alt_), "wrapAlt");
  }
};

struct MethodHandleOffsets : public CheckOffsets<mirror::MethodHandle> {
  MethodHandleOffsets() : CheckOffsets<mirror::MethodHandle>(
      false, "Ljava/lang/invoke/MethodHandle;") {
    addOffset(OFFSETOF_MEMBER(mirror::MethodHandle, art_field_or_method_), "artFieldOrMethod");
    addOffset(OFFSETOF_MEMBER(mirror::MethodHandle, as_type_cache_), "asTypeCache");
    addOffset(OFFSETOF_MEMBER(mirror::MethodHandle, cached_spread_invoker_),
              "cachedSpreadInvoker");
    addOffset(OFFSETOF_MEMBER(mirror::MethodHandle, handle_kind_), "handleKind");
    addOffset(OFFSETOF_MEMBER(mirror::MethodHandle, method_type_), "type");
  }
};

struct MethodHandleImplOffsets : public CheckOffsets<mirror::MethodHandleImpl> {
  MethodHandleImplOffsets() : CheckOffsets<mirror::MethodHandleImpl>(
      false, "Ljava/lang/invoke/MethodHandleImpl;") {
    addOffset(OFFSETOF_MEMBER(mirror::MethodHandleImpl, info_), "info");
  }
};

struct MethodHandlesLookupOffsets : public CheckOffsets<mirror::MethodHandlesLookup> {
  MethodHandlesLookupOffsets() : CheckOffsets<mirror::MethodHandlesLookup>(
      false, "Ljava/lang/invoke/MethodHandles$Lookup;") {
    addOffset(OFFSETOF_MEMBER(mirror::MethodHandlesLookup, allowed_modes_), "allowedModes");
    addOffset(OFFSETOF_MEMBER(mirror::MethodHandlesLookup, lookup_class_), "lookupClass");
  }
};

struct EmulatedStackFrameOffsets : public CheckOffsets<mirror::EmulatedStackFrame> {
  EmulatedStackFrameOffsets() : CheckOffsets<mirror::EmulatedStackFrame>(
      false, "Ldalvik/system/EmulatedStackFrame;") {
    addOffset(OFFSETOF_MEMBER(mirror::EmulatedStackFrame, references_), "references");
    addOffset(OFFSETOF_MEMBER(mirror::EmulatedStackFrame, stack_frame_), "stackFrame");
    addOffset(OFFSETOF_MEMBER(mirror::EmulatedStackFrame, type_), "type");
  }
};

struct CallSiteOffsets : public CheckOffsets<mirror::CallSite> {
  CallSiteOffsets() : CheckOffsets<mirror::CallSite>(
      false, "Ljava/lang/invoke/CallSite;") {
    addOffset(OFFSETOF_MEMBER(mirror::CallSite, target_), "target");
  }
};

struct VarHandleOffsets : public CheckOffsets<mirror::VarHandle> {
  VarHandleOffsets() : CheckOffsets<mirror::VarHandle>(
      false, "Ljava/lang/invoke/VarHandle;") {
    addOffset(OFFSETOF_MEMBER(mirror::VarHandle, access_modes_bit_mask_), "accessModesBitMask");
    addOffset(OFFSETOF_MEMBER(mirror::VarHandle, coordinate_type0_), "coordinateType0");
    addOffset(OFFSETOF_MEMBER(mirror::VarHandle, coordinate_type1_), "coordinateType1");
    addOffset(OFFSETOF_MEMBER(mirror::VarHandle, var_type_), "varType");
  }
};

struct FieldVarHandleOffsets : public CheckOffsets<mirror::FieldVarHandle> {
  FieldVarHandleOffsets() : CheckOffsets<mirror::FieldVarHandle>(
      false, "Ljava/lang/invoke/FieldVarHandle;") {
    addOffset(OFFSETOF_MEMBER(mirror::FieldVarHandle, art_field_), "artField");
  }
};

struct StaticFieldVarHandleOffsets : public CheckOffsets<mirror::StaticFieldVarHandle> {
  StaticFieldVarHandleOffsets() : CheckOffsets<mirror::StaticFieldVarHandle>(
      false, "Ljava/lang/invoke/StaticFieldVarHandle;") {
    addOffset(OFFSETOF_MEMBER(mirror::StaticFieldVarHandle, declaring_class_), "declaringClass");
  }
};

struct ArrayElementVarHandleOffsets : public CheckOffsets<mirror::ArrayElementVarHandle> {
  ArrayElementVarHandleOffsets() : CheckOffsets<mirror::ArrayElementVarHandle>(
      false, "Ljava/lang/invoke/ArrayElementVarHandle;") {
  }
};

struct ByteArrayViewVarHandleOffsets : public CheckOffsets<mirror::ByteArrayViewVarHandle> {
  ByteArrayViewVarHandleOffsets() : CheckOffsets<mirror::ByteArrayViewVarHandle>(
      false, "Ljava/lang/invoke/ByteArrayViewVarHandle;") {
    addOffset(OFFSETOF_MEMBER(mirror::ByteArrayViewVarHandle, native_byte_order_),
              "nativeByteOrder");
  }
};

struct ByteBufferViewVarHandleOffsets : public CheckOffsets<mirror::ByteBufferViewVarHandle> {
  ByteBufferViewVarHandleOffsets() : CheckOffsets<mirror::ByteBufferViewVarHandle>(
      false, "Ljava/lang/invoke/ByteBufferViewVarHandle;") {
    addOffset(OFFSETOF_MEMBER(mirror::ByteBufferViewVarHandle, native_byte_order_),
              "nativeByteOrder");
  }
};

// C++ fields must exactly match the fields in the Java classes. If this fails,
// reorder the fields in the C++ class. Managed class fields are ordered by
// ClassLinker::LinkFieldsHelper::LinkFields.
TEST_F(ClassLinkerTest, ValidateFieldOrderOfJavaCppUnionClasses) {
  ScopedObjectAccess soa(Thread::Current());
  EXPECT_TRUE(ObjectOffsets().Check());
  EXPECT_TRUE(ClassOffsets().Check());
  EXPECT_TRUE(ClassExtOffsets().Check());
  EXPECT_TRUE(StringOffsets().Check());
  EXPECT_TRUE(ThrowableOffsets().Check());
  EXPECT_TRUE(StackTraceElementOffsets().Check());
  EXPECT_TRUE(ClassLoaderOffsets().Check());
  EXPECT_TRUE(ProxyOffsets().Check());
  EXPECT_TRUE(DexCacheOffsets().Check());
  EXPECT_TRUE(ReferenceOffsets().Check());
  EXPECT_TRUE(FinalizerReferenceOffsets().Check());
  EXPECT_TRUE(AccessibleObjectOffsets().Check());
  EXPECT_TRUE(FieldOffsets().Check());
  EXPECT_TRUE(ExecutableOffsets().Check());
  EXPECT_TRUE(MethodTypeOffsets().Check());
  EXPECT_TRUE(MethodHandleOffsets().Check());
  EXPECT_TRUE(MethodHandleImplOffsets().Check());
  EXPECT_TRUE(MethodHandlesLookupOffsets().Check());
  EXPECT_TRUE(EmulatedStackFrameOffsets().Check());
  EXPECT_TRUE(CallSiteOffsets().Check());
  EXPECT_TRUE(VarHandleOffsets().Check());
  EXPECT_TRUE(FieldVarHandleOffsets().Check());
  EXPECT_TRUE(ArrayElementVarHandleOffsets().Check());
  EXPECT_TRUE(ByteArrayViewVarHandleOffsets().Check());
  EXPECT_TRUE(ByteBufferViewVarHandleOffsets().Check());
  EXPECT_TRUE(StackFrameInfoOffsets().Check());
}

TEST_F(ClassLinkerTest, FindClassNonexistent) {
  ScopedObjectAccess soa(Thread::Current());
  AssertNonExistentClass("NoSuchClass;");
  AssertNonExistentClass("LNoSuchClass;");
}

TEST_F(ClassLinkerTest, GetDexFiles) {
  ScopedObjectAccess soa(Thread::Current());

  jobject jclass_loader = LoadDex("Nested");
  std::vector<const DexFile*> dex_files(GetDexFiles(jclass_loader));
  ASSERT_EQ(dex_files.size(), 1U);
  EXPECT_TRUE(android::base::EndsWith(dex_files[0]->GetLocation(), "Nested.jar"));

  jobject jclass_loader2 = LoadDex("MultiDex");
  std::vector<const DexFile*> dex_files2(GetDexFiles(jclass_loader2));
  ASSERT_EQ(dex_files2.size(), 2U);
  EXPECT_TRUE(android::base::EndsWith(dex_files2[0]->GetLocation(), "MultiDex.jar"));
}

TEST_F(ClassLinkerTest, FindClassNested) {
  ScopedObjectAccess soa(Thread::Current());
  StackHandleScope<1> hs(soa.Self());
  Handle<mirror::ClassLoader> class_loader(
      hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Nested"))));

  ObjPtr<mirror::Class> outer = class_linker_->FindClass(soa.Self(), "LNested;", class_loader);
  ASSERT_TRUE(outer != nullptr);
  EXPECT_EQ(0U, outer->NumVirtualMethods());
  EXPECT_EQ(1U, outer->NumDirectMethods());

  ObjPtr<mirror::Class> inner =
      class_linker_->FindClass(soa.Self(), "LNested$Inner;", class_loader);
  ASSERT_TRUE(inner != nullptr);
  EXPECT_EQ(0U, inner->NumVirtualMethods());
  EXPECT_EQ(1U, inner->NumDirectMethods());
}

TEST_F(ClassLinkerTest, FindClass_Primitives) {
  ScopedObjectAccess soa(Thread::Current());
  const std::string expected("BCDFIJSZV");
  for (int ch = 1; ch < 256; ++ch) {
    std::string descriptor;
    descriptor.push_back(ch);
    if (expected.find(ch) == std::string::npos) {
      AssertNonExistentClass(descriptor);
    } else {
      AssertPrimitiveClass(descriptor);
    }
  }
}

TEST_F(ClassLinkerTest, FindClass) {
  ScopedObjectAccess soa(Thread::Current());
  StackHandleScope<2> hs(soa.Self());
  Handle<mirror::Class> JavaLangObject = hs.NewHandle(
      class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;"));
  AssertObjectClass(JavaLangObject.Get());

  Handle<mirror::ClassLoader> class_loader(
      hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("MyClass"))));
  AssertNonExistentClass("LMyClass;");
  ObjPtr<mirror::Class> MyClass = class_linker_->FindClass(soa.Self(), "LMyClass;", class_loader);
  ASSERT_TRUE(MyClass != nullptr);
  ASSERT_TRUE(MyClass->GetClass() != nullptr);
  ASSERT_OBJ_PTR_EQ(MyClass->GetClass(), MyClass->GetClass()->GetClass());
  EXPECT_OBJ_PTR_EQ(JavaLangObject.Get(), MyClass->GetClass()->GetSuperClass());
  std::string temp;
  ASSERT_STREQ(MyClass->GetDescriptor(&temp), "LMyClass;");
  EXPECT_OBJ_PTR_EQ(MyClass->GetSuperClass(), JavaLangObject.Get());
  EXPECT_TRUE(MyClass->HasSuperClass());
  EXPECT_OBJ_PTR_EQ(class_loader.Get(), MyClass->GetClassLoader());
  EXPECT_EQ(ClassStatus::kResolved, MyClass->GetStatus());
  EXPECT_FALSE(MyClass->IsErroneous());
  EXPECT_TRUE(MyClass->IsLoaded());
  EXPECT_TRUE(MyClass->IsResolved());
  EXPECT_FALSE(MyClass->IsErroneousResolved());
  EXPECT_FALSE(MyClass->IsVerified());
  EXPECT_FALSE(MyClass->IsInitialized());
  EXPECT_FALSE(MyClass->IsArrayInstance());
  EXPECT_FALSE(MyClass->IsArrayClass());
  EXPECT_TRUE(MyClass->GetComponentType() == nullptr);
  EXPECT_FALSE(MyClass->IsInterface());
  EXPECT_FALSE(MyClass->IsPublic());
  EXPECT_FALSE(MyClass->IsFinal());
  EXPECT_FALSE(MyClass->IsPrimitive());
  EXPECT_FALSE(MyClass->IsSynthetic());
  EXPECT_EQ(1U, MyClass->NumDirectMethods());
  EXPECT_EQ(0U, MyClass->NumVirtualMethods());
  EXPECT_EQ(0U, MyClass->NumInstanceFields());
  EXPECT_EQ(0U, MyClass->NumStaticFields());
  EXPECT_EQ(0U, MyClass->NumDirectInterfaces());

  EXPECT_OBJ_PTR_EQ(JavaLangObject->GetClass()->GetClass(), MyClass->GetClass()->GetClass());

  // created by class_linker
  AssertArrayClass("[C", "C", nullptr);
  AssertArrayClass("[Ljava/lang/Object;", "Ljava/lang/Object;", nullptr);
  // synthesized on the fly
  AssertArrayClass("[[C", "[C", nullptr);
  AssertArrayClass("[[[LMyClass;", "[[LMyClass;", class_loader.Get());
  // or not available at all
  AssertNonExistentClass("[[[[LNonExistentClass;");
}

TEST_F(ClassLinkerTest, LookupResolvedType) {
  ScopedObjectAccess soa(Thread::Current());
  StackHandleScope<1> hs(soa.Self());
  Handle<mirror::ClassLoader> class_loader(
      hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("MyClass"))));
  AssertNonExistentClass("LMyClass;");
  ObjPtr<mirror::Class> klass = class_linker_->FindClass(soa.Self(), "LMyClass;", class_loader);
  dex::TypeIndex type_idx = klass->GetClassDef()->class_idx_;
  ObjPtr<mirror::DexCache> dex_cache = klass->GetDexCache();
  EXPECT_OBJ_PTR_EQ(
      class_linker_->LookupResolvedType(type_idx, dex_cache, class_loader.Get()),
      klass);
  // Zero out the resolved type and make sure LookupResolvedType still finds it.
  dex_cache->ClearResolvedType(type_idx);
  EXPECT_TRUE(dex_cache->GetResolvedType(type_idx) == nullptr);
  EXPECT_OBJ_PTR_EQ(
      class_linker_->LookupResolvedType(type_idx, dex_cache, class_loader.Get()),
      klass);
}

TEST_F(ClassLinkerTest, LookupResolvedTypeArray) {
  ScopedObjectAccess soa(Thread::Current());
  StackHandleScope<2> hs(soa.Self());
  Handle<mirror::ClassLoader> class_loader(
      hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("AllFields"))));
  // Get the AllFields class for the dex cache and dex file.
  ObjPtr<mirror::Class> all_fields_klass
      = class_linker_->FindClass(soa.Self(), "LAllFields;", class_loader);
  ASSERT_TRUE(all_fields_klass != nullptr);
  Handle<mirror::DexCache> dex_cache = hs.NewHandle(all_fields_klass->GetDexCache());
  const DexFile& dex_file = *dex_cache->GetDexFile();
  // Get the index of the array class we want to test.
  const dex::TypeId* array_id = dex_file.FindTypeId("[Ljava/lang/Object;");
  ASSERT_TRUE(array_id != nullptr);
  dex::TypeIndex array_idx = dex_file.GetIndexForTypeId(*array_id);
  // Check that the array class wasn't resolved yet.
  EXPECT_TRUE(
      class_linker_->LookupResolvedType(array_idx, dex_cache.Get(), class_loader.Get()) == nullptr);
  // Resolve the array class we want to test.
  ObjPtr<mirror::Class> array_klass
      = class_linker_->FindClass(soa.Self(), "[Ljava/lang/Object;", class_loader);
  ASSERT_TRUE(array_klass != nullptr);
  // Test that LookupResolvedType() finds the array class.
  EXPECT_OBJ_PTR_EQ(
      class_linker_->LookupResolvedType(array_idx, dex_cache.Get(), class_loader.Get()),
      array_klass);
  // Zero out the resolved type and make sure LookupResolvedType() still finds it.
  dex_cache->ClearResolvedType(array_idx);
  EXPECT_TRUE(dex_cache->GetResolvedType(array_idx) == nullptr);
  EXPECT_OBJ_PTR_EQ(
      class_linker_->LookupResolvedType(array_idx, dex_cache.Get(), class_loader.Get()),
      array_klass);
}

TEST_F(ClassLinkerTest, LookupResolvedTypeErroneousInit) {
  ScopedObjectAccess soa(Thread::Current());
  StackHandleScope<3> hs(soa.Self());
  Handle<mirror::ClassLoader> class_loader(
      hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("ErroneousInit"))));
  AssertNonExistentClass("LErroneousInit;");
  Handle<mirror::Class> klass =
      hs.NewHandle(class_linker_->FindClass(soa.Self(), "LErroneousInit;", class_loader));
  ASSERT_TRUE(klass != nullptr);
  dex::TypeIndex type_idx = klass->GetClassDef()->class_idx_;
  Handle<mirror::DexCache> dex_cache = hs.NewHandle(klass->GetDexCache());
  EXPECT_OBJ_PTR_EQ(
      class_linker_->LookupResolvedType(type_idx, dex_cache.Get(), class_loader.Get()),
      klass.Get());
  // Zero out the resolved type and make sure LookupResolvedType still finds it.
  dex_cache->ClearResolvedType(type_idx);
  EXPECT_TRUE(dex_cache->GetResolvedType(type_idx) == nullptr);
  EXPECT_OBJ_PTR_EQ(
      class_linker_->LookupResolvedType(type_idx, dex_cache.Get(), class_loader.Get()),
      klass.Get());
  // Force initialization to turn the class erroneous.
  bool initialized = class_linker_->EnsureInitialized(soa.Self(),
                                                      klass,
                                                      /* can_init_fields= */ true,
                                                      /* can_init_parents= */ true);
  EXPECT_FALSE(initialized);
  EXPECT_TRUE(soa.Self()->IsExceptionPending());
  soa.Self()->ClearException();
  // Check that the LookupResolvedType() can still find the resolved type.
  EXPECT_OBJ_PTR_EQ(
      class_linker_->LookupResolvedType(type_idx, dex_cache.Get(), class_loader.Get()),
      klass.Get());
  // Zero out the resolved type and make sure LookupResolvedType() still finds it.
  dex_cache->ClearResolvedType(type_idx);
  EXPECT_TRUE(dex_cache->GetResolvedType(type_idx) == nullptr);
  EXPECT_OBJ_PTR_EQ(
      class_linker_->LookupResolvedType(type_idx, dex_cache.Get(), class_loader.Get()),
      klass.Get());
}

TEST_F(ClassLinkerTest, LibCore) {
  ScopedObjectAccess soa(Thread::Current());
  ASSERT_TRUE(java_lang_dex_file_ != nullptr);
  AssertDexFile(*java_lang_dex_file_, nullptr);
}

// The first reference array element must be a multiple of 4 bytes from the
// start of the object
TEST_F(ClassLinkerTest, ValidateObjectArrayElementsOffset) {
  ScopedObjectAccess soa(Thread::Current());
  ObjPtr<mirror::Class> array_class =
      class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/String;");
  ObjPtr<mirror::ObjectArray<mirror::String>> array =
      mirror::ObjectArray<mirror::String>::Alloc(soa.Self(), array_class, 0);
  uintptr_t data_offset =
      reinterpret_cast<uintptr_t>(array->GetRawData(sizeof(mirror::HeapReference<mirror::String>),
                                                    0));
  if (sizeof(mirror::HeapReference<mirror::String>) == sizeof(int32_t)) {
    EXPECT_TRUE(IsAligned<4>(data_offset));  // Check 4 byte alignment.
  } else {
    EXPECT_TRUE(IsAligned<8>(data_offset));  // Check 8 byte alignment.
  }
}

TEST_F(ClassLinkerTest, ValidatePrimitiveArrayElementsOffset) {
  ScopedObjectAccess soa(Thread::Current());
  StackHandleScope<5> hs(soa.Self());
  Handle<mirror::LongArray> long_array(hs.NewHandle(mirror::LongArray::Alloc(soa.Self(), 0)));
  EXPECT_OBJ_PTR_EQ(class_linker_->FindSystemClass(soa.Self(), "[J"), long_array->GetClass());
  uintptr_t data_offset = reinterpret_cast<uintptr_t>(long_array->GetData());
  EXPECT_TRUE(IsAligned<8>(data_offset));  // Longs require 8 byte alignment

  Handle<mirror::DoubleArray> double_array(hs.NewHandle(mirror::DoubleArray::Alloc(soa.Self(), 0)));
  EXPECT_OBJ_PTR_EQ(class_linker_->FindSystemClass(soa.Self(), "[D"), double_array->GetClass());
  data_offset = reinterpret_cast<uintptr_t>(double_array->GetData());
  EXPECT_TRUE(IsAligned<8>(data_offset));  // Doubles require 8 byte alignment

  Handle<mirror::IntArray> int_array(hs.NewHandle(mirror::IntArray::Alloc(soa.Self(), 0)));
  EXPECT_OBJ_PTR_EQ(class_linker_->FindSystemClass(soa.Self(), "[I"), int_array->GetClass());
  data_offset = reinterpret_cast<uintptr_t>(int_array->GetData());
  EXPECT_TRUE(IsAligned<4>(data_offset));  // Ints require 4 byte alignment

  Handle<mirror::CharArray> char_array(hs.NewHandle(mirror::CharArray::Alloc(soa.Self(), 0)));
  EXPECT_OBJ_PTR_EQ(class_linker_->FindSystemClass(soa.Self(), "[C"), char_array->GetClass());
  data_offset = reinterpret_cast<uintptr_t>(char_array->GetData());
  EXPECT_TRUE(IsAligned<2>(data_offset));  // Chars require 2 byte alignment

  Handle<mirror::ShortArray> short_array(hs.NewHandle(mirror::ShortArray::Alloc(soa.Self(), 0)));
  EXPECT_OBJ_PTR_EQ(class_linker_->FindSystemClass(soa.Self(), "[S"), short_array->GetClass());
  data_offset = reinterpret_cast<uintptr_t>(short_array->GetData());
  EXPECT_TRUE(IsAligned<2>(data_offset));  // Shorts require 2 byte alignment

  // Take it as given that bytes and booleans have byte alignment
}

TEST_F(ClassLinkerTest, ValidateBoxedTypes) {
  // Validate that the "value" field is always the 0th field in each of java.lang's box classes.
  // This lets UnboxPrimitive avoid searching for the field by name at runtime.
  ScopedObjectAccess soa(Thread::Current());
  ScopedNullHandle<mirror::ClassLoader> class_loader;
  ObjPtr<mirror::Class> c;
  c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Boolean;", class_loader);
  EXPECT_STREQ("value", c->GetIFieldsPtr()->At(0).GetName());
  c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Byte;", class_loader);
  EXPECT_STREQ("value", c->GetIFieldsPtr()->At(0).GetName());
  c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Character;", class_loader);
  EXPECT_STREQ("value", c->GetIFieldsPtr()->At(0).GetName());
  c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Double;", class_loader);
  EXPECT_STREQ("value", c->GetIFieldsPtr()->At(0).GetName());
  c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Float;", class_loader);
  EXPECT_STREQ("value", c->GetIFieldsPtr()->At(0).GetName());
  c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Integer;", class_loader);
  EXPECT_STREQ("value", c->GetIFieldsPtr()->At(0).GetName());
  c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Long;", class_loader);
  EXPECT_STREQ("value", c->GetIFieldsPtr()->At(0).GetName());
  c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Short;", class_loader);
  EXPECT_STREQ("value", c->GetIFieldsPtr()->At(0).GetName());
}

TEST_F(ClassLinkerTest, TwoClassLoadersOneClass) {
  ScopedObjectAccess soa(Thread::Current());
  StackHandleScope<3> hs(soa.Self());
  Handle<mirror::ClassLoader> class_loader_1(
      hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("MyClass"))));
  Handle<mirror::ClassLoader> class_loader_2(
      hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("MyClass"))));
  Handle<mirror::Class> MyClass_1 = hs.NewHandle(
      class_linker_->FindClass(soa.Self(), "LMyClass;", class_loader_1));
  ObjPtr<mirror::Class> MyClass_2 =
      class_linker_->FindClass(soa.Self(), "LMyClass;", class_loader_2);
  EXPECT_TRUE(MyClass_1 != nullptr);
  EXPECT_TRUE(MyClass_2 != nullptr);
  EXPECT_OBJ_PTR_NE(MyClass_1.Get(), MyClass_2);
}

TEST_F(ClassLinkerTest, StaticFields) {
  ScopedObjectAccess soa(Thread::Current());
  StackHandleScope<2> hs(soa.Self());
  Handle<mirror::ClassLoader> class_loader(
      hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Statics"))));
  Handle<mirror::Class> statics(
      hs.NewHandle(class_linker_->FindClass(soa.Self(), "LStatics;", class_loader)));
  class_linker_->EnsureInitialized(soa.Self(), statics, true, true);

  // Static final primitives that are initialized by a compile-time constant
  // expression resolve to a copy of a constant value from the constant pool.
  // So <clinit> should be null.
  ArtMethod* clinit = statics->FindClassMethod("<clinit>", "()V", kRuntimePointerSize);
  EXPECT_TRUE(clinit == nullptr);

  EXPECT_EQ(9U, statics->NumStaticFields());

  ArtField* s0 = statics->FindStaticField("s0", "Z");
  EXPECT_EQ(s0->GetTypeAsPrimitiveType(), Primitive::kPrimBoolean);
  EXPECT_EQ(true, s0->GetBoolean(statics.Get()));
  s0->SetBoolean<false>(statics.Get(), false);

  ArtField* s1 = statics->FindStaticField("s1", "B");
  EXPECT_EQ(s1->GetTypeAsPrimitiveType(), Primitive::kPrimByte);
  EXPECT_EQ(5, s1->GetByte(statics.Get()));
  s1->SetByte<false>(statics.Get(), 6);

  ArtField* s2 = statics->FindStaticField("s2", "C");
  EXPECT_EQ(s2->GetTypeAsPrimitiveType(), Primitive::kPrimChar);
  EXPECT_EQ('a', s2->GetChar(statics.Get()));
  s2->SetChar<false>(statics.Get(), 'b');

  ArtField* s3 = statics->FindStaticField("s3", "S");
  EXPECT_EQ(s3->GetTypeAsPrimitiveType(), Primitive::kPrimShort);
  EXPECT_EQ(-536, s3->GetShort(statics.Get()));
  s3->SetShort<false>(statics.Get(), -535);

  ArtField* s4 = statics->FindStaticField("s4", "I");
  EXPECT_EQ(s4->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
  EXPECT_EQ(2000000000, s4->GetInt(statics.Get()));
  s4->SetInt<false>(statics.Get(), 2000000001);

  ArtField* s5 = statics->FindStaticField("s5", "J");
  EXPECT_EQ(s5->GetTypeAsPrimitiveType(), Primitive::kPrimLong);
  EXPECT_EQ(0x1234567890abcdefLL, s5->GetLong(statics.Get()));
  s5->SetLong<false>(statics.Get(), INT64_C(0x34567890abcdef12));

  ArtField* s6 = statics->FindStaticField("s6", "F");
  EXPECT_EQ(s6->GetTypeAsPrimitiveType(), Primitive::kPrimFloat);
  EXPECT_DOUBLE_EQ(0.5, s6->GetFloat(statics.Get()));
  s6->SetFloat<false>(statics.Get(), 0.75);

  ArtField* s7 = statics->FindStaticField("s7", "D");
  EXPECT_EQ(s7->GetTypeAsPrimitiveType(), Primitive::kPrimDouble);
  EXPECT_DOUBLE_EQ(16777217.0, s7->GetDouble(statics.Get()));
  s7->SetDouble<false>(statics.Get(), 16777219);

  ArtField* s8 = statics->FindStaticField("s8", "Ljava/lang/String;");
  EXPECT_EQ(s8->GetTypeAsPrimitiveType(), Primitive::kPrimNot);
  EXPECT_TRUE(s8->GetObject(statics.Get())->AsString()->Equals("android"));
  ObjPtr<mirror::String> str_value = mirror::String::AllocFromModifiedUtf8(soa.Self(), "robot");
  s8->SetObject<false>(s8->GetDeclaringClass(), str_value);

  // TODO: Remove EXPECT_FALSE when GCC can handle EXPECT_EQ
  // http://code.google.com/p/googletest/issues/detail?id=322
  EXPECT_FALSE(s0->GetBoolean(statics.Get()));
  EXPECT_EQ(6, s1->GetByte(statics.Get()));
  EXPECT_EQ('b', s2->GetChar(statics.Get()));
  EXPECT_EQ(-535, s3->GetShort(statics.Get()));
  EXPECT_EQ(2000000001, s4->GetInt(statics.Get()));
  EXPECT_EQ(INT64_C(0x34567890abcdef12), s5->GetLong(statics.Get()));
  EXPECT_FLOAT_EQ(0.75, s6->GetFloat(statics.Get()));
  EXPECT_DOUBLE_EQ(16777219.0, s7->GetDouble(statics.Get()));
  EXPECT_TRUE(s8->GetObject(statics.Get())->AsString()->Equals("robot"));
}

TEST_F(ClassLinkerTest, Interfaces) {
  ScopedObjectAccess soa(Thread::Current());
  StackHandleScope<6> hs(soa.Self());
  Handle<mirror::ClassLoader> class_loader(
      hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Interfaces"))));
  Handle<mirror::Class> I(
      hs.NewHandle(class_linker_->FindClass(soa.Self(), "LInterfaces$I;", class_loader)));
  Handle<mirror::Class> J(
      hs.NewHandle(class_linker_->FindClass(soa.Self(), "LInterfaces$J;", class_loader)));
  Handle<mirror::Class> K(
      hs.NewHandle(class_linker_->FindClass(soa.Self(), "LInterfaces$K;", class_loader)));
  Handle<mirror::Class> A(
      hs.NewHandle(class_linker_->FindClass(soa.Self(), "LInterfaces$A;", class_loader)));
  Handle<mirror::Class> B(
      hs.NewHandle(class_linker_->FindClass(soa.Self(), "LInterfaces$B;", class_loader)));
  EXPECT_TRUE(I->IsAssignableFrom(A.Get()));
  EXPECT_TRUE(J->IsAssignableFrom(A.Get()));
  EXPECT_TRUE(J->IsAssignableFrom(K.Get()));
  EXPECT_TRUE(K->IsAssignableFrom(B.Get()));
  EXPECT_TRUE(J->IsAssignableFrom(B.Get()));

  const std::string_view void_sig("()V");
  ArtMethod* Ii = I->FindClassMethod("i", void_sig, kRuntimePointerSize);
  ArtMethod* Jj1 = J->FindClassMethod("j1", void_sig, kRuntimePointerSize);
  ArtMethod* Jj2 = J->FindClassMethod("j2", void_sig, kRuntimePointerSize);
  ArtMethod* Kj1 = K->FindInterfaceMethod("j1", void_sig, kRuntimePointerSize);
  ArtMethod* Kj2 = K->FindInterfaceMethod("j2", void_sig, kRuntimePointerSize);
  ArtMethod* Kk = K->FindInterfaceMethod("k", void_sig, kRuntimePointerSize);
  ArtMethod* Ai = A->FindClassMethod("i", void_sig, kRuntimePointerSize);
  ArtMethod* Aj1 = A->FindClassMethod("j1", void_sig, kRuntimePointerSize);
  ArtMethod* Aj2 = A->FindClassMethod("j2", void_sig, kRuntimePointerSize);
  ASSERT_TRUE(Ii != nullptr);
  ASSERT_FALSE(Ii->IsDirect());
  ASSERT_TRUE(Jj1 != nullptr);
  ASSERT_FALSE(Jj1->IsDirect());
  ASSERT_TRUE(Jj2 != nullptr);
  ASSERT_FALSE(Jj2->IsDirect());
  ASSERT_TRUE(Kj1 != nullptr);
  ASSERT_TRUE(Kj2 != nullptr);
  ASSERT_TRUE(Kk != nullptr);
  ASSERT_TRUE(Ai != nullptr);
  ASSERT_FALSE(Ai->IsDirect());
  ASSERT_TRUE(Aj1 != nullptr);
  ASSERT_FALSE(Aj1->IsDirect());
  ASSERT_TRUE(Aj2 != nullptr);
  ASSERT_FALSE(Aj2->IsDirect());
  EXPECT_NE(Ii, Ai);
  EXPECT_NE(Jj1, Aj1);
  EXPECT_NE(Jj2, Aj2);
  EXPECT_EQ(Kj1, Jj1);
  EXPECT_EQ(Kj2, Jj2);
  EXPECT_EQ(Ai, A->FindVirtualMethodForInterface(Ii, kRuntimePointerSize));
  EXPECT_EQ(Aj1, A->FindVirtualMethodForInterface(Jj1, kRuntimePointerSize));
  EXPECT_EQ(Aj2, A->FindVirtualMethodForInterface(Jj2, kRuntimePointerSize));
  EXPECT_EQ(Ai, A->FindVirtualMethodForVirtualOrInterface(Ii, kRuntimePointerSize));
  EXPECT_EQ(Aj1, A->FindVirtualMethodForVirtualOrInterface(Jj1, kRuntimePointerSize));
  EXPECT_EQ(Aj2, A->FindVirtualMethodForVirtualOrInterface(Jj2, kRuntimePointerSize));

  ArtField* Afoo = A->FindStaticField("foo", "Ljava/lang/String;");
  ArtField* Bfoo = B->FindStaticField("foo", "Ljava/lang/String;");
  ArtField* Jfoo = J->FindStaticField("foo", "Ljava/lang/String;");
  ArtField* Kfoo = K->FindStaticField("foo", "Ljava/lang/String;");
  ASSERT_TRUE(Afoo != nullptr);
  EXPECT_EQ(Afoo, Bfoo);
  EXPECT_EQ(Afoo, Jfoo);
  EXPECT_EQ(Afoo, Kfoo);
}

TEST_F(ClassLinkerTest, ResolveVerifyAndClinit) {
  // pretend we are trying to get the static storage for the StaticsFromCode class.

  // case 1, get the uninitialized storage from StaticsFromCode.<clinit>
  // case 2, get the initialized storage from StaticsFromCode.getS0

  ScopedObjectAccess soa(Thread::Current());
  jobject jclass_loader = LoadDex("StaticsFromCode");
  const DexFile* dex_file = GetFirstDexFile(jclass_loader);
  StackHandleScope<1> hs(soa.Self());
  Handle<mirror::ClassLoader> class_loader(
      hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader)));
  ObjPtr<mirror::Class> klass =
      class_linker_->FindClass(soa.Self(), "LStaticsFromCode;", class_loader);
  ArtMethod* clinit = klass->FindClassInitializer(kRuntimePointerSize);
  ArtMethod* getS0 =
      klass->FindClassMethod("getS0", "()Ljava/lang/Object;", kRuntimePointerSize);
  ASSERT_TRUE(getS0 != nullptr);
  ASSERT_TRUE(getS0->IsStatic());
  const dex::TypeId* type_id = dex_file->FindTypeId("LStaticsFromCode;");
  ASSERT_TRUE(type_id != nullptr);
  dex::TypeIndex type_idx = dex_file->GetIndexForTypeId(*type_id);
  ObjPtr<mirror::Class> uninit = ResolveVerifyAndClinit(type_idx,
                                                        clinit,
                                                        soa.Self(),
                                                        /* can_run_clinit= */ true,
                                                        /* verify_access= */ false);
  EXPECT_TRUE(uninit != nullptr);
  EXPECT_FALSE(uninit->IsInitialized());
  ObjPtr<mirror::Class> init = ResolveVerifyAndClinit(type_idx,
                                                      getS0,
                                                      soa.Self(),
                                                      /* can_run_clinit= */ true,
                                                      /* verify_access= */ false);
  EXPECT_TRUE(init != nullptr);
  EXPECT_TRUE(init->IsInitialized());
}

TEST_F(ClassLinkerTest, ErroneousClass) {
  ScopedObjectAccess soa(Thread::Current());
  jobject jclass_loader = LoadMultiDex("ErroneousA", "ErroneousB");
  StackHandleScope<1> hs(soa.Self());
  Handle<mirror::ClassLoader> class_loader(
      hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader)));
  hs.Self()->AssertNoPendingException();
  const char* descriptor = "LErroneous;";
  ObjPtr<mirror::Class> klass = class_linker_->FindClass(soa.Self(), descriptor, class_loader);
  // Erronenous since we are extending final class.
  hs.Self()->AssertPendingException();
  EXPECT_TRUE(klass == nullptr);
  klass = class_linker_->LookupClass(soa.Self(), descriptor, class_loader.Get());
  EXPECT_FALSE(klass == nullptr);
  EXPECT_TRUE(klass->IsErroneous());
  EXPECT_TRUE(klass->GetIfTable() != nullptr);
}

TEST_F(ClassLinkerTest, FinalizableBit) {
  ScopedObjectAccess soa(Thread::Current());
  ObjPtr<mirror::Class> c;

  // Object has a finalize method, but we know it's empty.
  c = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;");
  EXPECT_FALSE(c->IsFinalizable());

  // Enum has a finalize method to prevent its subclasses from implementing one.
  c = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Enum;");
  EXPECT_FALSE(c->IsFinalizable());

  // RoundingMode is an enum.
  c = class_linker_->FindSystemClass(soa.Self(), "Ljava/math/RoundingMode;");
  EXPECT_FALSE(c->IsFinalizable());

  // RandomAccessFile extends Object and overrides finalize.
  c = class_linker_->FindSystemClass(soa.Self(), "Ljava/io/RandomAccessFile;");
  EXPECT_TRUE(c->IsFinalizable());

  // FileInputStream is finalizable and extends InputStream which isn't.
  c = class_linker_->FindSystemClass(soa.Self(), "Ljava/io/InputStream;");
  EXPECT_FALSE(c->IsFinalizable());
  c = class_linker_->FindSystemClass(soa.Self(), "Ljava/io/FileInputStream;");
  EXPECT_TRUE(c->IsFinalizable());

  // ScheduledThreadPoolExecutor doesn't have a finalize method but
  // extends ThreadPoolExecutor which does.
  c = class_linker_->FindSystemClass(soa.Self(), "Ljava/util/concurrent/ThreadPoolExecutor;");
  EXPECT_TRUE(c->IsFinalizable());
  c = class_linker_->FindSystemClass(soa.Self(), "Ljava/util/concurrent/ScheduledThreadPoolExecutor;");
  EXPECT_TRUE(c->IsFinalizable());
}

TEST_F(ClassLinkerTest, ClassRootDescriptors) {
  ScopedObjectAccess soa(Thread::Current());
  std::string temp;
  for (size_t i = 0; i < static_cast<size_t>(ClassRoot::kMax); i++) {
    ObjPtr<mirror::Class> klass = GetClassRoot(ClassRoot(i), class_linker_);
    EXPECT_GT(strlen(klass->GetDescriptor(&temp)), 0U);
    EXPECT_STREQ(klass->GetDescriptor(&temp), GetClassRootDescriptor(ClassRoot(i))) << " i = " << i;
  }
}

TEST_F(ClassLinkerTest, ValidatePredefinedClassSizes) {
  ScopedObjectAccess soa(Thread::Current());
  ScopedNullHandle<mirror::ClassLoader> class_loader;
  ObjPtr<mirror::Class> c;

  c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Class;", class_loader);
  ASSERT_TRUE(c != nullptr);
  EXPECT_EQ(c->GetClassSize(), mirror::Class::ClassClassSize(kRuntimePointerSize));

  c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Object;", class_loader);
  ASSERT_TRUE(c != nullptr);
  EXPECT_EQ(c->GetClassSize(), mirror::Object::ClassSize(kRuntimePointerSize));

  c = class_linker_->FindClass(soa.Self(), "Ljava/lang/String;", class_loader);
  ASSERT_TRUE(c != nullptr);
  EXPECT_EQ(c->GetClassSize(), mirror::String::ClassSize(kRuntimePointerSize));

  c = class_linker_->FindClass(soa.Self(), "Ljava/lang/DexCache;", class_loader);
  ASSERT_TRUE(c != nullptr);
  EXPECT_EQ(c->GetClassSize(), mirror::DexCache::ClassSize(kRuntimePointerSize));
}

static void CheckMethod(ArtMethod* method, bool verified)
    REQUIRES_SHARED(Locks::mutator_lock_) {
  if (!method->IsNative() && !method->IsAbstract()) {
    EXPECT_EQ((method->GetAccessFlags() & kAccSkipAccessChecks) != 0U, verified)
        << method->PrettyMethod(true);
  }
}

static void CheckVerificationAttempted(ObjPtr<mirror::Class> c, bool preverified)
    REQUIRES_SHARED(Locks::mutator_lock_) {
  for (auto& m : c->GetMethods(kRuntimePointerSize)) {
    CheckMethod(&m, preverified);
  }
}

TEST_F(ClassLinkerTest, Preverified_InitializedBoot) {
  ScopedObjectAccess soa(Thread::Current());

  ObjPtr<mirror::Class> JavaLangObject =
      class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;");
  ASSERT_TRUE(JavaLangObject != nullptr);
  EXPECT_TRUE(JavaLangObject->IsInitialized()) << "Not testing already initialized class from the "
                                                  "core";
  CheckVerificationAttempted(JavaLangObject, true);
}

TEST_F(ClassLinkerTest, Preverified_UninitializedBoot) {
  ScopedObjectAccess soa(Thread::Current());

  StackHandleScope<1> hs(soa.Self());

  Handle<mirror::Class> security_manager(hs.NewHandle(class_linker_->FindSystemClass(
      soa.Self(), "Ljava/lang/SecurityManager;")));
  EXPECT_FALSE(security_manager->IsInitialized()) << "Not testing uninitialized class from the "
                                                     "core";

  CheckVerificationAttempted(security_manager.Get(), false);

  class_linker_->EnsureInitialized(soa.Self(), security_manager, true, true);
  CheckVerificationAttempted(security_manager.Get(), true);
}

TEST_F(ClassLinkerTest, Preverified_App) {
  ScopedObjectAccess soa(Thread::Current());

  StackHandleScope<2> hs(soa.Self());
  Handle<mirror::ClassLoader> class_loader(
      hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Statics"))));
  Handle<mirror::Class> statics(
      hs.NewHandle(class_linker_->FindClass(soa.Self(), "LStatics;", class_loader)));

  CheckVerificationAttempted(statics.Get(), false);

  class_linker_->EnsureInitialized(soa.Self(), statics, true, true);
  CheckVerificationAttempted(statics.Get(), true);
}

TEST_F(ClassLinkerTest, IsBootStrapClassLoaded) {
  ScopedObjectAccess soa(Thread::Current());

  StackHandleScope<3> hs(soa.Self());
  Handle<mirror::ClassLoader> class_loader(
      hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Statics"))));

  // java.lang.Object is a bootstrap class.
  Handle<mirror::Class> jlo_class(
      hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/Object;")));
  ASSERT_TRUE(jlo_class != nullptr);
  EXPECT_TRUE(jlo_class->IsBootStrapClassLoaded());

  // Statics is not a bootstrap class.
  Handle<mirror::Class> statics(
      hs.NewHandle(class_linker_->FindClass(soa.Self(), "LStatics;", class_loader)));
  ASSERT_TRUE(statics != nullptr);
  EXPECT_FALSE(statics->IsBootStrapClassLoaded());
}

// Regression test for b/26799552.
TEST_F(ClassLinkerTest, RegisterDexFileName) {
  ScopedObjectAccess soa(Thread::Current());
  StackHandleScope<2> hs(soa.Self());
  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
  MutableHandle<mirror::DexCache> dex_cache(hs.NewHandle<mirror::DexCache>(nullptr));
  {
    ReaderMutexLock mu(soa.Self(), *Locks::dex_lock_);
    for (const auto& entry : class_linker->GetDexCachesData()) {
      const ClassLinker::DexCacheData& data = entry.second;
      dex_cache.Assign(soa.Self()->DecodeJObject(data.weak_root)->AsDexCache());
      if (dex_cache != nullptr) {
        break;
      }
    }
    ASSERT_TRUE(dex_cache != nullptr);
  }
  const uint16_t data[] = { 0x20AC, 0x20A1 };
  Handle<mirror::String> location(hs.NewHandle(mirror::String::AllocFromUtf16(soa.Self(),
                                                                              arraysize(data),
                                                                              data)));
  const DexFile* old_dex_file = dex_cache->GetDexFile();

  auto container =
      std::make_shared<MemoryDexFileContainer>(old_dex_file->Begin(), old_dex_file->Size());
  std::unique_ptr<DexFile> dex_file(new StandardDexFile(old_dex_file->Begin(),
                                                        old_dex_file->Size(),
                                                        location->ToModifiedUtf8(),
                                                        0u,
                                                        nullptr,
                                                        std::move(container)));
  // Make a copy of the dex cache with changed name.
  dex_cache.Assign(class_linker->AllocAndInitializeDexCache(Thread::Current(),
                                                            *dex_file,
                                                            /* class_loader= */ nullptr));
  DCHECK_EQ(dex_cache->GetLocation()->CompareTo(location.Get()), 0);
  {
    WriterMutexLock mu(soa.Self(), *Locks::dex_lock_);
    // Check that inserting with a UTF16 name works.
    class_linker->RegisterDexFileLocked(*dex_file, dex_cache.Get(), /* class_loader= */ nullptr);
  }
}

TEST_F(ClassLinkerMethodHandlesTest, TestResolveMethodTypes) {
  ScopedObjectAccess soa(Thread::Current());
  StackHandleScope<7> hs(soa.Self());

  Handle<mirror::ClassLoader> class_loader(
      hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("MethodTypes"))));
  Handle<mirror::Class> method_types(
      hs.NewHandle(class_linker_->FindClass(soa.Self(), "LMethodTypes;", class_loader)));
  class_linker_->EnsureInitialized(soa.Self(), method_types, true, true);

  ArtMethod* method1 = method_types->FindClassMethod(
      "method1",
      "(Ljava/lang/String;)Ljava/lang/String;",
      kRuntimePointerSize);
  ASSERT_TRUE(method1 != nullptr);
  ASSERT_FALSE(method1->IsDirect());

  const DexFile& dex_file = *(method1->GetDexFile());
  Handle<mirror::DexCache> dex_cache = hs.NewHandle(
      class_linker_->FindDexCache(soa.Self(), dex_file));

  const dex::MethodId& method1_id = dex_file.GetMethodId(method1->GetDexMethodIndex());

  // This is the MethodType corresponding to the prototype of
  // String MethodTypes# method1(String).
  // Its RType = Ljava/lang/String;
  // Its PTypes = { Ljava/lang/String; }
  Handle<mirror::MethodType> method1_type = hs.NewHandle(
      class_linker_->ResolveMethodType(soa.Self(), method1_id.proto_idx_, dex_cache, class_loader));

  // Assert that the method type was resolved successfully.
  ASSERT_TRUE(method1_type != nullptr);

  // Assert that the return type and the method arguments are as we expect.
  Handle<mirror::Class> string_class(hs.NewHandle(class_linker_->FindClass(soa.Self(),
                                                                           "Ljava/lang/String;",
                                                                           class_loader)));
  ASSERT_OBJ_PTR_EQ(string_class.Get(), method1_type->GetRType());
  ASSERT_OBJ_PTR_EQ(string_class.Get(), method1_type->GetPTypes()->Get(0));

  // Resolve the method type again and assert that we get back the same value.
  Handle<mirror::MethodType> method1_type2 = hs.NewHandle(
      class_linker_->ResolveMethodType(soa.Self(), method1_id.proto_idx_, dex_cache, class_loader));
  ASSERT_OBJ_PTR_EQ(method1_type.Get(), method1_type2.Get());

  // Resolve the MethodType associated with a different method signature
  // and assert it's different.
  ArtMethod* method2 = method_types->FindClassMethod(
      "method2",
      "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
      kRuntimePointerSize);
  ASSERT_TRUE(method2 != nullptr);
  ASSERT_FALSE(method2->IsDirect());
  const dex::MethodId& method2_id = dex_file.GetMethodId(method2->GetDexMethodIndex());
  Handle<mirror::MethodType> method2_type = hs.NewHandle(
      class_linker_->ResolveMethodType(soa.Self(), method2_id.proto_idx_, dex_cache, class_loader));
  ASSERT_OBJ_PTR_NE(method1_type.Get(), method2_type.Get());
}

// Verify that ClassLinker's CreateWellknownClassLoader works as expected
// by creating a chain of class loaders with various dex files.
TEST_F(ClassLinkerTest, CreateWellKnownClassLoader) {
  // LoadDexIn*ClassLoader methods already assert that the parent loader is the expected one.
  // No need to check again.
  jobject class_loader_a = LoadDexInPathClassLoader("MyClass", nullptr);
  jobject class_loader_b = LoadDexInDelegateLastClassLoader("Nested", class_loader_a);
  jobject class_loader_c = LoadDexInPathClassLoader("MultiDex", class_loader_b);
  LoadDexInDelegateLastClassLoader("Interfaces", class_loader_c);
}

TEST_F(ClassLinkerTest, PrettyClass) {
  ScopedObjectAccess soa(Thread::Current());
  EXPECT_EQ("null", mirror::Class::PrettyClass(nullptr));
  ObjPtr<mirror::Class> c = class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/String;");
  ASSERT_TRUE(c != nullptr);
  ObjPtr<mirror::Object> o = mirror::ObjectArray<mirror::String>::Alloc(soa.Self(), c, 0);
  EXPECT_EQ("java.lang.Class<java.lang.String[]>", mirror::Class::PrettyClass(o->GetClass()));
}

TEST_F(ClassLinkerTest, PrettyClassAndClassLoader) {
  ScopedObjectAccess soa(Thread::Current());
  EXPECT_EQ("null", mirror::Class::PrettyClassAndClassLoader(nullptr));
  ObjPtr<mirror::Class> c = class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/String;");
  ASSERT_TRUE(c != nullptr);
  ObjPtr<mirror::Object> o = mirror::ObjectArray<mirror::String>::Alloc(soa.Self(), c, 0);
  EXPECT_EQ("java.lang.Class<java.lang.String[],null>",
            mirror::Class::PrettyClassAndClassLoader(o->GetClass()));
}

TEST_F(ClassLinkerTest, PrettyField) {
  ScopedObjectAccess soa(Thread::Current());
  EXPECT_EQ("null", ArtField::PrettyField(nullptr));

  ObjPtr<mirror::Class> java_lang_String = class_linker_->FindSystemClass(soa.Self(),
                                                                          "Ljava/lang/String;");

  ArtField* f;
  f = java_lang_String->FindDeclaredInstanceField("count", "I");
  EXPECT_EQ("int java.lang.String.count", f->PrettyField());
  EXPECT_EQ("java.lang.String.count", f->PrettyField(false));
}

TEST_F(ClassLinkerTest, JniShortName_JniLongName) {
  ScopedObjectAccess soa(Thread::Current());
  ObjPtr<mirror::Class> c = class_linker_->FindSystemClass(soa.Self(), "Ljava/lang/String;");
  ASSERT_TRUE(c != nullptr);
  ArtMethod* m;

  m = c->FindClassMethod("charAt", "(I)C", kRuntimePointerSize);
  ASSERT_TRUE(m != nullptr);
  ASSERT_FALSE(m->IsDirect());
  EXPECT_EQ("Java_java_lang_String_charAt", m->JniShortName());
  EXPECT_EQ("Java_java_lang_String_charAt__I", m->JniLongName());

  m = c->FindClassMethod("indexOf", "(Ljava/lang/String;I)I", kRuntimePointerSize);
  ASSERT_TRUE(m != nullptr);
  ASSERT_FALSE(m->IsDirect());
  EXPECT_EQ("Java_java_lang_String_indexOf", m->JniShortName());
  EXPECT_EQ("Java_java_lang_String_indexOf__Ljava_lang_String_2I", m->JniLongName());

  m = c->FindClassMethod("copyValueOf", "([CII)Ljava/lang/String;", kRuntimePointerSize);
  ASSERT_TRUE(m != nullptr);
  ASSERT_TRUE(m->IsStatic());
  EXPECT_EQ("Java_java_lang_String_copyValueOf", m->JniShortName());
  EXPECT_EQ("Java_java_lang_String_copyValueOf___3CII", m->JniLongName());
}

class ClassLinkerClassLoaderTest : public ClassLinkerTest {
 protected:
  // Verifies that the class identified by the given descriptor is loaded with
  // the expected_class_loader_obj when search from class_loader_to_search_obj.
  // When expected_class_loader_obj is null the check will be done against BootClassLoader.
  void VerifyClassResolution(const std::string& descriptor,
                             jobject class_loader_to_search_obj,
                             jobject expected_class_loader_obj,
                             bool should_find = true) {
    Thread* self = Thread::Current();
    ScopedObjectAccess soa(self);
    StackHandleScope<3> hs(self);
    Handle<mirror::ClassLoader> class_loader_to_search(
        hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_to_search_obj)));

    Handle<mirror::Class> klass = hs.NewHandle(
        class_linker_->FindClass(soa.Self(), descriptor.c_str(), class_loader_to_search));

    if (!should_find) {
      if (self->IsExceptionPending()) {
        self->ClearException();
      }
      ASSERT_TRUE(klass == nullptr);
    } else if (expected_class_loader_obj == nullptr) {
      ASSERT_TRUE(ClassLinker::IsBootClassLoader(klass->GetClassLoader()));
    } else {
      ASSERT_TRUE(klass != nullptr) << descriptor;
      Handle<mirror::ClassLoader> expected_class_loader(
          hs.NewHandle(soa.Decode<mirror::ClassLoader>(expected_class_loader_obj)));
      ASSERT_OBJ_PTR_EQ(klass->GetClassLoader(), expected_class_loader.Get());
    }
  }
};

TEST_F(ClassLinkerClassLoaderTest, CreatePathClassLoader) {
  jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
  VerifyClassResolution("LDefinedInA;", class_loader_a, class_loader_a);
  VerifyClassResolution("Ljava/lang/String;", class_loader_a, nullptr);
  VerifyClassResolution("LDefinedInB;", class_loader_a, nullptr, /*should_find=*/ false);
}

TEST_F(ClassLinkerClassLoaderTest, CreateDelegateLastClassLoader) {
  jobject class_loader_a = LoadDexInDelegateLastClassLoader("ForClassLoaderA", nullptr);
  VerifyClassResolution("LDefinedInA;", class_loader_a, class_loader_a);
  VerifyClassResolution("Ljava/lang/String;", class_loader_a, nullptr);
  VerifyClassResolution("LDefinedInB;", class_loader_a, nullptr, /*should_find=*/ false);
}

TEST_F(ClassLinkerClassLoaderTest, CreateClassLoaderChain) {
  // The chain is
  //    ClassLoaderA (PathClassLoader, defines: A, AB, AC, AD)
  //       ^
  //       |
  //    ClassLoaderB (DelegateLastClassLoader, defines: B, AB, BC, BD)
  //       ^
  //       |
  //    ClassLoaderC (PathClassLoader, defines: C, AC, BC, CD)
  //       ^
  //       |
  //    ClassLoaderD (DelegateLastClassLoader, defines: D, AD, BD, CD)

  jobject class_loader_a = LoadDexInPathClassLoader("ForClassLoaderA", nullptr);
  jobject class_loader_b = LoadDexInDelegateLastClassLoader("ForClassLoaderB", class_loader_a);
  jobject class_loader_c = LoadDexInPathClassLoader("ForClassLoaderC", class_loader_b);
  jobject class_loader_d = LoadDexInDelegateLastClassLoader("ForClassLoaderD", class_loader_c);

  // Verify exclusive classes (present in only one class loader).
  VerifyClassResolution("LDefinedInD;", class_loader_d, class_loader_d);
  VerifyClassResolution("LDefinedInC;", class_loader_d, class_loader_c);
  VerifyClassResolution("LDefinedInB;", class_loader_d, class_loader_b);
  VerifyClassResolution("LDefinedInA;", class_loader_d, class_loader_a);

  // Verify classes that are defined in multiple classloader.

  // Classes defined in B should be found in B even if they are defined in A or C because
  // B is a DelegateLastClassLoader.
  VerifyClassResolution("LDefinedInAB;", class_loader_d, class_loader_b);
  VerifyClassResolution("LDefinedInABC;", class_loader_d, class_loader_b);
  VerifyClassResolution("LDefinedInBC;", class_loader_d, class_loader_b);

  // Classes defined in D should be found in D even if they are defined in parent class loaders
  // as well because D is a DelegateLastClassLoader.
  VerifyClassResolution("LDefinedInAD;", class_loader_d, class_loader_d);
  VerifyClassResolution("LDefinedInBD;", class_loader_d, class_loader_d);
  VerifyClassResolution("LDefinedInCD;", class_loader_d, class_loader_d);


  // Classes not defined in the DelegateLastClassLoaders (i.e. D or B) should be found
  // in the top parent.
  VerifyClassResolution("LDefinedInAC;", class_loader_d, class_loader_a);

  // Check that we don't find an undefined class.
  VerifyClassResolution("LNotDefined;", class_loader_d, nullptr, /*should_find=*/ false);
}

}  // namespace art
