Move ArtField to native

Add linear alloc. Moved ArtField to be native object. Changed image
writer to put ArtFields after the mirror section.

Savings:
2MB on low ram devices
4MB on normal devices

Total PSS measurements before (normal N5, 95s after shell start):
Image size: 7729152 bytes
23112 kB: .NonMoving
23212 kB: .NonMoving
22868 kB: .NonMoving
23072 kB: .NonMoving
22836 kB: .NonMoving
19618 kB: .Zygote
19850 kB: .Zygote
19623 kB: .Zygote
19924 kB: .Zygote
19612 kB: .Zygote
Avg: 42745.4 kB

After:
Image size: 7462912 bytes
17440 kB: .NonMoving
16776 kB: .NonMoving
16804 kB: .NonMoving
17812 kB: .NonMoving
16820 kB: .NonMoving
18788 kB: .Zygote
18856 kB: .Zygote
19064 kB: .Zygote
18841 kB: .Zygote
18629 kB: .Zygote
3499 kB: .LinearAlloc
3408 kB: .LinearAlloc
3424 kB: .LinearAlloc
3600 kB: .LinearAlloc
3436 kB: .LinearAlloc
Avg: 39439.4 kB

No reflection performance changes.

Bug: 19264997
Bug: 17643507

Change-Id: I10c73a37913332080aeb978c7c94713bdfe4fe1c
diff --git a/runtime/mirror/array-inl.h b/runtime/mirror/array-inl.h
index 6452f31..8b3418d 100644
--- a/runtime/mirror/array-inl.h
+++ b/runtime/mirror/array-inl.h
@@ -203,7 +203,7 @@
 template<typename T>
 inline PrimitiveArray<T>* PrimitiveArray<T>::Alloc(Thread* self, size_t length) {
   Array* raw_array = Array::Alloc<true>(self, GetArrayClass(), length,
-                                        ComponentSizeShiftWidth<sizeof(T)>(),
+                                        ComponentSizeShiftWidth(sizeof(T)),
                                         Runtime::Current()->GetHeap()->GetCurrentAllocator());
   return down_cast<PrimitiveArray<T>*>(raw_array);
 }
diff --git a/runtime/mirror/array.h b/runtime/mirror/array.h
index 115fcf2..832ad68 100644
--- a/runtime/mirror/array.h
+++ b/runtime/mirror/array.h
@@ -54,7 +54,7 @@
   }
 
   void SetLength(int32_t length) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    CHECK_GE(length, 0);
+    DCHECK_GE(length, 0);
     // We use non transactional version since we can't undo this write. We also disable checking
     // since it would fail during a transaction.
     SetField32<false, false, kVerifyNone>(OFFSET_OF_OBJECT_MEMBER(Array, length_), length);
diff --git a/runtime/mirror/art_field-inl.h b/runtime/mirror/art_field-inl.h
deleted file mode 100644
index 986852f..0000000
--- a/runtime/mirror/art_field-inl.h
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef ART_RUNTIME_MIRROR_ART_FIELD_INL_H_
-#define ART_RUNTIME_MIRROR_ART_FIELD_INL_H_
-
-#include "art_field.h"
-
-#include "base/logging.h"
-#include "class_linker.h"
-#include "dex_cache.h"
-#include "gc/accounting/card_table-inl.h"
-#include "jvalue.h"
-#include "object-inl.h"
-#include "primitive.h"
-#include "thread-inl.h"
-#include "scoped_thread_state_change.h"
-#include "well_known_classes.h"
-
-namespace art {
-namespace mirror {
-
-inline uint32_t ArtField::ClassSize() {
-  uint32_t vtable_entries = Object::kVTableLength;
-  return Class::ComputeClassSize(true, vtable_entries, 0, 0, 0, 0, 0);
-}
-
-inline Class* ArtField::GetDeclaringClass() {
-  Class* result = GetFieldObject<Class>(OFFSET_OF_OBJECT_MEMBER(ArtField, declaring_class_));
-  DCHECK(result != NULL);
-  DCHECK(result->IsLoaded() || result->IsErroneous());
-  return result;
-}
-
-inline void ArtField::SetDeclaringClass(Class *new_declaring_class) {
-  SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(ArtField, declaring_class_), new_declaring_class);
-}
-
-inline uint32_t ArtField::GetAccessFlags() {
-  DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
-  return GetField32(OFFSET_OF_OBJECT_MEMBER(ArtField, access_flags_));
-}
-
-inline MemberOffset ArtField::GetOffset() {
-  DCHECK(GetDeclaringClass()->IsResolved() || GetDeclaringClass()->IsErroneous());
-  return MemberOffset(GetField32(OFFSET_OF_OBJECT_MEMBER(ArtField, offset_)));
-}
-
-inline MemberOffset ArtField::GetOffsetDuringLinking() {
-  DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
-  return MemberOffset(GetField32(OFFSET_OF_OBJECT_MEMBER(ArtField, offset_)));
-}
-
-inline uint32_t ArtField::Get32(Object* object) {
-  DCHECK(object != nullptr) << PrettyField(this);
-  DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
-  if (UNLIKELY(IsVolatile())) {
-    return object->GetField32Volatile(GetOffset());
-  }
-  return object->GetField32(GetOffset());
-}
-
-template<bool kTransactionActive>
-inline void ArtField::Set32(Object* object, uint32_t new_value) {
-  DCHECK(object != nullptr) << PrettyField(this);
-  DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
-  if (UNLIKELY(IsVolatile())) {
-    object->SetField32Volatile<kTransactionActive>(GetOffset(), new_value);
-  } else {
-    object->SetField32<kTransactionActive>(GetOffset(), new_value);
-  }
-}
-
-inline uint64_t ArtField::Get64(Object* object) {
-  DCHECK(object != NULL) << PrettyField(this);
-  DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
-  if (UNLIKELY(IsVolatile())) {
-    return object->GetField64Volatile(GetOffset());
-  }
-  return object->GetField64(GetOffset());
-}
-
-template<bool kTransactionActive>
-inline void ArtField::Set64(Object* object, uint64_t new_value) {
-  DCHECK(object != NULL) << PrettyField(this);
-  DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
-  if (UNLIKELY(IsVolatile())) {
-    object->SetField64Volatile<kTransactionActive>(GetOffset(), new_value);
-  } else {
-    object->SetField64<kTransactionActive>(GetOffset(), new_value);
-  }
-}
-
-inline Object* ArtField::GetObj(Object* object) {
-  DCHECK(object != NULL) << PrettyField(this);
-  DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
-  if (UNLIKELY(IsVolatile())) {
-    return object->GetFieldObjectVolatile<Object>(GetOffset());
-  }
-  return object->GetFieldObject<Object>(GetOffset());
-}
-
-template<bool kTransactionActive>
-inline void ArtField::SetObj(Object* object, Object* new_value) {
-  DCHECK(object != NULL) << PrettyField(this);
-  DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
-  if (UNLIKELY(IsVolatile())) {
-    object->SetFieldObjectVolatile<kTransactionActive>(GetOffset(), new_value);
-  } else {
-    object->SetFieldObject<kTransactionActive>(GetOffset(), new_value);
-  }
-}
-
-#define FIELD_GET(object, type) \
-  DCHECK_EQ(Primitive::kPrim ## type, GetTypeAsPrimitiveType()) << PrettyField(this); \
-  DCHECK(object != nullptr) << PrettyField(this); \
-  DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted()); \
-  if (UNLIKELY(IsVolatile())) { \
-    return object->GetField ## type ## Volatile(GetOffset()); \
-  } \
-  return object->GetField ## type(GetOffset());
-
-#define FIELD_SET(object, type, value) \
-  DCHECK_EQ(Primitive::kPrim ## type, GetTypeAsPrimitiveType()) << PrettyField(this); \
-  DCHECK(object != nullptr) << PrettyField(this); \
-  DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted()); \
-  if (UNLIKELY(IsVolatile())) { \
-    object->SetField ## type ## Volatile<kTransactionActive>(GetOffset(), value); \
-  } else { \
-    object->SetField ## type<kTransactionActive>(GetOffset(), value); \
-  }
-
-inline uint8_t ArtField::GetBoolean(Object* object) {
-  FIELD_GET(object, Boolean);
-}
-
-template<bool kTransactionActive>
-inline void ArtField::SetBoolean(Object* object, uint8_t z) {
-  FIELD_SET(object, Boolean, z);
-}
-
-inline int8_t ArtField::GetByte(Object* object) {
-  FIELD_GET(object, Byte);
-}
-
-template<bool kTransactionActive>
-inline void ArtField::SetByte(Object* object, int8_t b) {
-  FIELD_SET(object, Byte, b);
-}
-
-inline uint16_t ArtField::GetChar(Object* object) {
-  FIELD_GET(object, Char);
-}
-
-template<bool kTransactionActive>
-inline void ArtField::SetChar(Object* object, uint16_t c) {
-  FIELD_SET(object, Char, c);
-}
-
-inline int16_t ArtField::GetShort(Object* object) {
-  FIELD_GET(object, Short);
-}
-
-template<bool kTransactionActive>
-inline void ArtField::SetShort(Object* object, int16_t s) {
-  FIELD_SET(object, Short, s);
-}
-
-#undef FIELD_GET
-#undef FIELD_SET
-
-inline int32_t ArtField::GetInt(Object* object) {
-  if (kIsDebugBuild) {
-    Primitive::Type type = GetTypeAsPrimitiveType();
-    CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField(this);
-  }
-  return Get32(object);
-}
-
-template<bool kTransactionActive>
-inline void ArtField::SetInt(Object* object, int32_t i) {
-  if (kIsDebugBuild) {
-    Primitive::Type type = GetTypeAsPrimitiveType();
-    CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField(this);
-  }
-  Set32<kTransactionActive>(object, i);
-}
-
-inline int64_t ArtField::GetLong(Object* object) {
-  if (kIsDebugBuild) {
-    Primitive::Type type = GetTypeAsPrimitiveType();
-    CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField(this);
-  }
-  return Get64(object);
-}
-
-template<bool kTransactionActive>
-inline void ArtField::SetLong(Object* object, int64_t j) {
-  if (kIsDebugBuild) {
-    Primitive::Type type = GetTypeAsPrimitiveType();
-    CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField(this);
-  }
-  Set64<kTransactionActive>(object, j);
-}
-
-inline float ArtField::GetFloat(Object* object) {
-  DCHECK_EQ(Primitive::kPrimFloat, GetTypeAsPrimitiveType()) << PrettyField(this);
-  JValue bits;
-  bits.SetI(Get32(object));
-  return bits.GetF();
-}
-
-template<bool kTransactionActive>
-inline void ArtField::SetFloat(Object* object, float f) {
-  DCHECK_EQ(Primitive::kPrimFloat, GetTypeAsPrimitiveType()) << PrettyField(this);
-  JValue bits;
-  bits.SetF(f);
-  Set32<kTransactionActive>(object, bits.GetI());
-}
-
-inline double ArtField::GetDouble(Object* object) {
-  DCHECK_EQ(Primitive::kPrimDouble, GetTypeAsPrimitiveType()) << PrettyField(this);
-  JValue bits;
-  bits.SetJ(Get64(object));
-  return bits.GetD();
-}
-
-template<bool kTransactionActive>
-inline void ArtField::SetDouble(Object* object, double d) {
-  DCHECK_EQ(Primitive::kPrimDouble, GetTypeAsPrimitiveType()) << PrettyField(this);
-  JValue bits;
-  bits.SetD(d);
-  Set64<kTransactionActive>(object, bits.GetJ());
-}
-
-inline Object* ArtField::GetObject(Object* object) {
-  DCHECK_EQ(Primitive::kPrimNot, GetTypeAsPrimitiveType()) << PrettyField(this);
-  return GetObj(object);
-}
-
-template<bool kTransactionActive>
-inline void ArtField::SetObject(Object* object, Object* l) {
-  DCHECK_EQ(Primitive::kPrimNot, GetTypeAsPrimitiveType()) << PrettyField(this);
-  SetObj<kTransactionActive>(object, l);
-}
-
-inline const char* ArtField::GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-  uint32_t field_index = GetDexFieldIndex();
-  if (UNLIKELY(GetDeclaringClass()->IsProxyClass())) {
-    DCHECK(IsStatic());
-    DCHECK_LT(field_index, 2U);
-    return field_index == 0 ? "interfaces" : "throws";
-  }
-  const DexFile* dex_file = GetDexFile();
-  return dex_file->GetFieldName(dex_file->GetFieldId(field_index));
-}
-
-inline const char* ArtField::GetTypeDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-  uint32_t field_index = GetDexFieldIndex();
-  if (UNLIKELY(GetDeclaringClass()->IsProxyClass())) {
-    DCHECK(IsStatic());
-    DCHECK_LT(field_index, 2U);
-    // 0 == Class[] interfaces; 1 == Class[][] throws;
-    return field_index == 0 ? "[Ljava/lang/Class;" : "[[Ljava/lang/Class;";
-  }
-  const DexFile* dex_file = GetDexFile();
-  const DexFile::FieldId& field_id = dex_file->GetFieldId(field_index);
-  return dex_file->GetFieldTypeDescriptor(field_id);
-}
-
-inline Primitive::Type ArtField::GetTypeAsPrimitiveType()
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-  return Primitive::GetType(GetTypeDescriptor()[0]);
-}
-
-inline bool ArtField::IsPrimitiveType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-  return GetTypeAsPrimitiveType() != Primitive::kPrimNot;
-}
-
-template <bool kResolve>
-inline Class* ArtField::GetType() {
-  const uint32_t field_index = GetDexFieldIndex();
-  auto* declaring_class = GetDeclaringClass();
-  if (UNLIKELY(declaring_class->IsProxyClass())) {
-    return Runtime::Current()->GetClassLinker()->FindSystemClass(Thread::Current(),
-                                                                 GetTypeDescriptor());
-  }
-  auto* dex_cache = declaring_class->GetDexCache();
-  const DexFile* const dex_file = dex_cache->GetDexFile();
-  const DexFile::FieldId& field_id = dex_file->GetFieldId(field_index);
-  mirror::Class* type = dex_cache->GetResolvedType(field_id.type_idx_);
-  if (kResolve && UNLIKELY(type == nullptr)) {
-    type = Runtime::Current()->GetClassLinker()->ResolveType(field_id.type_idx_, this);
-    CHECK(type != nullptr || Thread::Current()->IsExceptionPending());
-  }
-  return type;
-}
-
-inline size_t ArtField::FieldSize() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-  return Primitive::ComponentSize(GetTypeAsPrimitiveType());
-}
-
-inline mirror::DexCache* ArtField::GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-  return GetDeclaringClass()->GetDexCache();
-}
-
-inline const DexFile* ArtField::GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-  return GetDexCache()->GetDexFile();
-}
-
-inline String* ArtField::GetStringName(Thread* self, bool resolve) {
-  auto dex_field_index = GetDexFieldIndex();
-  CHECK_NE(dex_field_index, DexFile::kDexNoIndex);
-  auto* dex_cache = GetDexCache();
-  const auto* dex_file = dex_cache->GetDexFile();
-  const auto& field_id = dex_file->GetFieldId(dex_field_index);
-  auto* name = dex_cache->GetResolvedString(field_id.name_idx_);
-  if (resolve && name == nullptr) {
-    StackHandleScope<1> hs(self);
-    name = Runtime::Current()->GetClassLinker()->ResolveString(
-        *dex_file, field_id.name_idx_, hs.NewHandle(dex_cache));
-  }
-  return name;
-}
-
-}  // namespace mirror
-}  // namespace art
-
-#endif  // ART_RUNTIME_MIRROR_ART_FIELD_INL_H_
diff --git a/runtime/mirror/art_field.cc b/runtime/mirror/art_field.cc
deleted file mode 100644
index 83602d4..0000000
--- a/runtime/mirror/art_field.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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 "art_field.h"
-
-#include "art_field-inl.h"
-#include "gc/accounting/card_table-inl.h"
-#include "object-inl.h"
-#include "object_array-inl.h"
-#include "runtime.h"
-#include "scoped_thread_state_change.h"
-#include "utils.h"
-#include "well_known_classes.h"
-
-namespace art {
-namespace mirror {
-
-// TODO: Get global references for these
-GcRoot<Class> ArtField::java_lang_reflect_ArtField_;
-
-void ArtField::SetClass(Class* java_lang_reflect_ArtField) {
-  CHECK(java_lang_reflect_ArtField_.IsNull());
-  CHECK(java_lang_reflect_ArtField != NULL);
-  java_lang_reflect_ArtField_ = GcRoot<Class>(java_lang_reflect_ArtField);
-}
-
-void ArtField::ResetClass() {
-  CHECK(!java_lang_reflect_ArtField_.IsNull());
-  java_lang_reflect_ArtField_ = GcRoot<Class>(nullptr);
-}
-
-void ArtField::SetOffset(MemberOffset num_bytes) {
-  DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
-  if (kIsDebugBuild && Runtime::Current()->IsAotCompiler() &&
-      Runtime::Current()->IsCompilingBootImage()) {
-    Primitive::Type type = GetTypeAsPrimitiveType();
-    if (type == Primitive::kPrimDouble || type == Primitive::kPrimLong) {
-      DCHECK_ALIGNED(num_bytes.Uint32Value(), 8);
-    }
-  }
-  // Not called within a transaction.
-  SetField32<false>(OFFSET_OF_OBJECT_MEMBER(ArtField, offset_), num_bytes.Uint32Value());
-}
-
-void ArtField::VisitRoots(RootVisitor* visitor) {
-  java_lang_reflect_ArtField_.VisitRootIfNonNull(visitor, RootInfo(kRootStickyClass));
-}
-
-// TODO: we could speed up the search if fields are ordered by offsets.
-ArtField* ArtField::FindInstanceFieldWithOffset(mirror::Class* klass, uint32_t field_offset) {
-  DCHECK(klass != nullptr);
-  ObjectArray<ArtField>* instance_fields = klass->GetIFields();
-  if (instance_fields != nullptr) {
-    for (int32_t i = 0, e = instance_fields->GetLength(); i < e; ++i) {
-      mirror::ArtField* field = instance_fields->GetWithoutChecks(i);
-      if (field->GetOffset().Uint32Value() == field_offset) {
-        return field;
-      }
-    }
-  }
-  // We did not find field in the class: look into superclass.
-  if (klass->GetSuperClass() != NULL) {
-    return FindInstanceFieldWithOffset(klass->GetSuperClass(), field_offset);
-  } else {
-    return nullptr;
-  }
-}
-
-}  // namespace mirror
-}  // namespace art
diff --git a/runtime/mirror/art_field.h b/runtime/mirror/art_field.h
deleted file mode 100644
index 9d95cb9..0000000
--- a/runtime/mirror/art_field.h
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef ART_RUNTIME_MIRROR_ART_FIELD_H_
-#define ART_RUNTIME_MIRROR_ART_FIELD_H_
-
-#include <jni.h>
-
-#include "gc_root.h"
-#include "modifiers.h"
-#include "object.h"
-#include "object_callbacks.h"
-#include "primitive.h"
-#include "read_barrier_option.h"
-
-namespace art {
-
-struct ArtFieldOffsets;
-class DexFile;
-class ScopedObjectAccessAlreadyRunnable;
-
-namespace mirror {
-
-class DexCache;
-
-// C++ mirror of java.lang.reflect.ArtField
-class MANAGED ArtField FINAL : public Object {
- public:
-  // Size of java.lang.reflect.ArtField.class.
-  static uint32_t ClassSize();
-
-  // Size of an instance of java.lang.reflect.ArtField not including its value array.
-  static constexpr uint32_t InstanceSize() {
-    return sizeof(ArtField);
-  }
-
-  Class* GetDeclaringClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
-  void SetDeclaringClass(Class *new_declaring_class) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
-  uint32_t GetAccessFlags() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
-  void SetAccessFlags(uint32_t new_access_flags) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    // Not called within a transaction.
-    SetField32<false>(OFFSET_OF_OBJECT_MEMBER(ArtField, access_flags_), new_access_flags);
-  }
-
-  bool IsPublic() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return (GetAccessFlags() & kAccPublic) != 0;
-  }
-
-  bool IsStatic() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return (GetAccessFlags() & kAccStatic) != 0;
-  }
-
-  bool IsFinal() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return (GetAccessFlags() & kAccFinal) != 0;
-  }
-
-  uint32_t GetDexFieldIndex() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return GetField32(OFFSET_OF_OBJECT_MEMBER(ArtField, field_dex_idx_));
-  }
-
-  void SetDexFieldIndex(uint32_t new_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    // Not called within a transaction.
-    SetField32<false>(OFFSET_OF_OBJECT_MEMBER(ArtField, field_dex_idx_), new_idx);
-  }
-
-  // Offset to field within an Object.
-  MemberOffset GetOffset() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
-  static MemberOffset OffsetOffset() {
-    return MemberOffset(OFFSETOF_MEMBER(ArtField, offset_));
-  }
-
-  MemberOffset GetOffsetDuringLinking() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
-  void SetOffset(MemberOffset num_bytes) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
-  // field access, null object for static fields
-  uint8_t GetBoolean(Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  template<bool kTransactionActive>
-  void SetBoolean(Object* object, uint8_t z) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  int8_t GetByte(Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  template<bool kTransactionActive>
-  void SetByte(Object* object, int8_t b) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  uint16_t GetChar(Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  template<bool kTransactionActive>
-  void SetChar(Object* object, uint16_t c) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  int16_t GetShort(Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  template<bool kTransactionActive>
-  void SetShort(Object* object, int16_t s) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  int32_t GetInt(Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  template<bool kTransactionActive>
-  void SetInt(Object* object, int32_t i) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  int64_t GetLong(Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  template<bool kTransactionActive>
-  void SetLong(Object* object, int64_t j) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  float GetFloat(Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  template<bool kTransactionActive>
-  void SetFloat(Object* object, float f) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  double GetDouble(Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  template<bool kTransactionActive>
-  void SetDouble(Object* object, double d) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  Object* GetObject(Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  template<bool kTransactionActive>
-  void SetObject(Object* object, Object* l) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
-  // Raw field accesses.
-  uint32_t Get32(Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  template<bool kTransactionActive>
-  void Set32(Object* object, uint32_t new_value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  uint64_t Get64(Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  template<bool kTransactionActive>
-  void Set64(Object* object, uint64_t new_value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  Object* GetObj(Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  template<bool kTransactionActive>
-  void SetObj(Object* object, Object* new_value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
-  template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
-  static Class* GetJavaLangReflectArtField()  SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    DCHECK(!java_lang_reflect_ArtField_.IsNull());
-    return java_lang_reflect_ArtField_.Read<kReadBarrierOption>();
-  }
-
-  static void SetClass(Class* java_lang_reflect_ArtField);
-  static void ResetClass();
-  static void VisitRoots(RootVisitor* visitor)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
-  bool IsVolatile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return (GetAccessFlags() & kAccVolatile) != 0;
-  }
-
-  // Returns an instance field with this offset in the given class or nullptr if not found.
-  static ArtField* FindInstanceFieldWithOffset(mirror::Class* klass, uint32_t field_offset)
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
-  const char* GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
-  // Resolves / returns the name from the dex cache.
-  String* GetStringName(Thread* self, bool resolve) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
-  const char* GetTypeDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
-  Primitive::Type GetTypeAsPrimitiveType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
-  bool IsPrimitiveType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
-  template <bool kResolve>
-  Class* GetType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
-  size_t FieldSize() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
-  mirror::DexCache* GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
-  const DexFile* GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- private:
-  // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
-  // The class we are a part of
-  HeapReference<Class> declaring_class_;
-
-  uint32_t access_flags_;
-
-  // Dex cache index of field id
-  uint32_t field_dex_idx_;
-
-  // Offset of field within an instance or in the Class' static fields
-  uint32_t offset_;
-
-  static GcRoot<Class> java_lang_reflect_ArtField_;
-
-  friend struct art::ArtFieldOffsets;  // for verifying offset information
-  DISALLOW_IMPLICIT_CONSTRUCTORS(ArtField);
-};
-
-}  // namespace mirror
-}  // namespace art
-
-#endif  // ART_RUNTIME_MIRROR_ART_FIELD_H_
diff --git a/runtime/mirror/art_method.cc b/runtime/mirror/art_method.cc
index edbbb4a..92aea1f 100644
--- a/runtime/mirror/art_method.cc
+++ b/runtime/mirror/art_method.cc
@@ -53,7 +53,7 @@
 
 ArtMethod* ArtMethod::FromReflectedMethod(const ScopedObjectAccessAlreadyRunnable& soa,
                                           jobject jlr_method) {
-  mirror::ArtField* f =
+  ArtField* f =
       soa.DecodeField(WellKnownClasses::java_lang_reflect_AbstractMethod_artMethod);
   mirror::ArtMethod* method = f->GetObject(soa.Decode<mirror::Object*>(jlr_method))->AsArtMethod();
   DCHECK(method != nullptr);
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index c368dc6..5b72e5a 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -397,9 +397,9 @@
   SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, iftable_), new_iftable);
 }
 
-inline ObjectArray<ArtField>* Class::GetIFields() {
+inline ArtField* Class::GetIFields() {
   DCHECK(IsLoaded() || IsErroneous());
-  return GetFieldObject<ObjectArray<ArtField>>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
+  return GetFieldPtr<ArtField*>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
 }
 
 inline MemberOffset Class::GetFirstReferenceInstanceFieldOffset() {
@@ -432,55 +432,46 @@
   return MemberOffset(base);
 }
 
-inline void Class::SetIFields(ObjectArray<ArtField>* new_ifields)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-  DCHECK(NULL == GetFieldObject<ObjectArray<ArtField>>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_)));
-  SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), new_ifields);
+inline void Class::SetIFields(ArtField* new_ifields) {
+  DCHECK(GetIFieldsUnchecked() == nullptr);
+  return SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), new_ifields);
 }
 
-inline ObjectArray<ArtField>* Class::GetSFields() {
+inline void Class::SetIFieldsUnchecked(ArtField* new_ifields) {
+  SetFieldPtr<false, true, kVerifyNone>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), new_ifields);
+}
+
+inline ArtField* Class::GetSFieldsUnchecked() {
+  return GetFieldPtr<ArtField*>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_));
+}
+
+inline ArtField* Class::GetIFieldsUnchecked() {
+  return GetFieldPtr<ArtField*>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
+}
+
+inline ArtField* Class::GetSFields() {
   DCHECK(IsLoaded() || IsErroneous()) << GetStatus();
-  return GetFieldObject<ObjectArray<ArtField>>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_));
+  return GetSFieldsUnchecked();
 }
 
-inline void Class::SetSFields(ObjectArray<ArtField>* new_sfields)
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+inline void Class::SetSFields(ArtField* new_sfields) {
   DCHECK((IsRetired() && new_sfields == nullptr) ||
-         (NULL == GetFieldObject<ObjectArray<ArtField>>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_))));
-  SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields);
+         GetFieldPtr<ArtField*>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_)) == nullptr);
+  SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields);
 }
 
-inline uint32_t Class::NumStaticFields() {
-  return (GetSFields() != NULL) ? GetSFields()->GetLength() : 0;
+inline void Class::SetSFieldsUnchecked(ArtField* new_sfields) {
+  SetFieldPtr<false, true, kVerifyNone>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields);
 }
 
-
-inline ArtField* Class::GetStaticField(uint32_t i)  // TODO: uint16_t
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-  return GetSFields()->GetWithoutChecks(i);
+inline ArtField* Class::GetStaticField(uint32_t i) {
+  DCHECK_LT(i, NumStaticFields());
+  return &GetSFields()[i];
 }
 
-inline void Class::SetStaticField(uint32_t i, ArtField* f)  // TODO: uint16_t
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-  ObjectArray<ArtField>* sfields= GetFieldObject<ObjectArray<ArtField>>(
-      OFFSET_OF_OBJECT_MEMBER(Class, sfields_));
-  sfields->Set<false>(i, f);
-}
-
-inline uint32_t Class::NumInstanceFields() {
-  return (GetIFields() != NULL) ? GetIFields()->GetLength() : 0;
-}
-
-inline ArtField* Class::GetInstanceField(uint32_t i) {  // TODO: uint16_t
-  DCHECK_NE(NumInstanceFields(), 0U);
-  return GetIFields()->GetWithoutChecks(i);
-}
-
-inline void Class::SetInstanceField(uint32_t i, ArtField* f)  // TODO: uint16_t
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-  ObjectArray<ArtField>* ifields= GetFieldObject<ObjectArray<ArtField>>(
-      OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
-  ifields->Set<false>(i, f);
+inline ArtField* Class::GetInstanceField(uint32_t i) {
+  DCHECK_LT(i, NumInstanceFields());
+  return &GetIFields()[i];
 }
 
 template<VerifyObjectFlags kVerifyFlags>
@@ -513,14 +504,12 @@
   DCHECK(IsIdxLoaded<kVerifyFlags>() || IsRetired<kVerifyFlags>() ||
          IsErroneous<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>() ||
          this == String::GetJavaLangString() ||
-         this == ArtField::GetJavaLangReflectArtField() ||
          this == ArtMethod::GetJavaLangReflectArtMethod())
       << "IsIdxLoaded=" << IsIdxLoaded<kVerifyFlags>()
       << " IsRetired=" << IsRetired<kVerifyFlags>()
       << " IsErroneous=" <<
           IsErroneous<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>()
       << " IsString=" << (this == String::GetJavaLangString())
-      << " IsArtField=" << (this == ArtField::GetJavaLangReflectArtField())
       << " IsArtMethod=" << (this == ArtMethod::GetJavaLangReflectArtMethod())
       << " descriptor=" << PrettyDescriptor(this);
   return GetField32<kVerifyFlags>(AccessFlagsOffset());
@@ -691,11 +680,6 @@
 }
 
 template<ReadBarrierOption kReadBarrierOption>
-inline bool Class::IsArtFieldClass() const {
-  return this == ArtField::GetJavaLangReflectArtField<kReadBarrierOption>();
-}
-
-template<ReadBarrierOption kReadBarrierOption>
 inline bool Class::IsArtMethodClass() const {
   return this == ArtMethod::GetJavaLangReflectArtMethod<kReadBarrierOption>();
 }
@@ -741,35 +725,35 @@
 inline ObjectArray<Class>* Class::GetInterfaces() {
   CHECK(IsProxyClass());
   // First static field.
-  DCHECK(GetSFields()->Get(0)->IsArtField());
-  DCHECK_STREQ(GetSFields()->Get(0)->GetName(), "interfaces");
-  MemberOffset field_offset = GetSFields()->Get(0)->GetOffset();
+  auto* field = GetStaticField(0);
+  DCHECK_STREQ(field->GetName(), "interfaces");
+  MemberOffset field_offset = field->GetOffset();
   return GetFieldObject<ObjectArray<Class>>(field_offset);
 }
 
 inline ObjectArray<ObjectArray<Class>>* Class::GetThrows() {
   CHECK(IsProxyClass());
   // Second static field.
-  DCHECK(GetSFields()->Get(1)->IsArtField());
-  DCHECK_STREQ(GetSFields()->Get(1)->GetName(), "throws");
-  MemberOffset field_offset = GetSFields()->Get(1)->GetOffset();
+  auto* field = GetStaticField(1);
+  DCHECK_STREQ(field->GetName(), "throws");
+  MemberOffset field_offset = field->GetOffset();
   return GetFieldObject<ObjectArray<ObjectArray<Class>>>(field_offset);
 }
 
 inline MemberOffset Class::GetDisableIntrinsicFlagOffset() {
   CHECK(IsReferenceClass());
   // First static field
-  DCHECK(GetSFields()->Get(0)->IsArtField());
-  DCHECK_STREQ(GetSFields()->Get(0)->GetName(), "disableIntrinsic");
-  return GetSFields()->Get(0)->GetOffset();
+  auto* field = GetStaticField(0);
+  DCHECK_STREQ(field->GetName(), "disableIntrinsic");
+  return field->GetOffset();
 }
 
 inline MemberOffset Class::GetSlowPathFlagOffset() {
   CHECK(IsReferenceClass());
   // Second static field
-  DCHECK(GetSFields()->Get(1)->IsArtField());
-  DCHECK_STREQ(GetSFields()->Get(1)->GetName(), "slowPathEnabled");
-  return GetSFields()->Get(1)->GetOffset();
+  auto* field = GetStaticField(1);
+  DCHECK_STREQ(field->GetName(), "slowPathEnabled");
+  return field->GetOffset();
 }
 
 inline bool Class::GetSlowPathEnabled() {
@@ -827,6 +811,24 @@
   return GetFieldObject<ObjectArray<String>>(DexCacheStringsOffset());
 }
 
+template<class Visitor>
+void mirror::Class::VisitFieldRoots(Visitor& visitor) {
+  ArtField* const sfields = GetSFieldsUnchecked();
+  for (size_t i = 0, count = NumStaticFields(); i < count; ++i) {
+    if (kIsDebugBuild && GetStatus() != kStatusRetired) {
+      CHECK_EQ(sfields[i].GetDeclaringClass(), this);
+    }
+    visitor.VisitRoot(sfields[i].DeclaringClassRoot().AddressWithoutBarrier());
+  }
+  ArtField* const ifields = GetIFieldsUnchecked();
+  for (size_t i = 0, count = NumInstanceFields(); i < count; ++i) {
+    if (kIsDebugBuild && GetStatus() != kStatusRetired) {
+      CHECK_EQ(ifields[i].GetDeclaringClass(), this);
+    }
+    visitor.VisitRoot(ifields[i].DeclaringClassRoot().AddressWithoutBarrier());
+  }
+}
+
 }  // namespace mirror
 }  // namespace art
 
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index b82a58f..92493bc 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -35,6 +35,7 @@
 
 namespace art {
 
+class ArtField;
 struct ClassOffsets;
 template<class T> class Handle;
 template<class T> class Handle;
@@ -44,7 +45,6 @@
 
 namespace mirror {
 
-class ArtField;
 class ArtMethod;
 class ClassLoader;
 class DexCache;
@@ -420,9 +420,6 @@
   bool IsThrowableClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
-  bool IsArtFieldClass() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
-  template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
   bool IsArtMethodClass() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
@@ -823,17 +820,22 @@
   ALWAYS_INLINE void SetIfTable(IfTable* new_iftable) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   // Get instance fields of the class (See also GetSFields).
-  ObjectArray<ArtField>* GetIFields() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  ArtField* GetIFields() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-  void SetIFields(ObjectArray<ArtField>* new_ifields) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  void SetIFields(ArtField* new_ifields) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-  uint32_t NumInstanceFields() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  // Unchecked edition has no verification flags.
+  void SetIFieldsUnchecked(ArtField* new_sfields) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-  ArtField* GetInstanceField(uint32_t i)  // TODO: uint16_t
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  uint32_t NumInstanceFields() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, num_instance_fields_));
+  }
 
-  void SetInstanceField(uint32_t i, ArtField* f)  // TODO: uint16_t
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  void SetNumInstanceFields(uint32_t num) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    return SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, num_instance_fields_), num);
+  }
+
+  ArtField* GetInstanceField(uint32_t i) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   // Returns the number of instance fields containing reference types.
   uint32_t NumReferenceInstanceFields() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -884,18 +886,24 @@
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   // Gets the static fields of the class.
-  ObjectArray<ArtField>* GetSFields() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  ArtField* GetSFields() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-  void SetSFields(ObjectArray<ArtField>* new_sfields) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  void SetSFields(ArtField* new_sfields) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-  uint32_t NumStaticFields() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  // Unchecked edition has no verification flags.
+  void SetSFieldsUnchecked(ArtField* new_sfields) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+  uint32_t NumStaticFields() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, num_static_fields_));
+  }
+
+  void SetNumStaticFields(uint32_t num) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    return SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, num_static_fields_), num);
+  }
 
   // TODO: uint16_t
   ArtField* GetStaticField(uint32_t i) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-  // TODO: uint16_t
-  void SetStaticField(uint32_t i, ArtField* f) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
   // Find a static or instance field using the JLS resolution order
   static ArtField* FindField(Thread* self, Handle<Class> klass, const StringPiece& name,
                              const StringPiece& type)
@@ -974,6 +982,10 @@
   static void VisitRoots(RootVisitor* visitor)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
+  template<class Visitor>
+  // Visit field roots.
+  void VisitFieldRoots(Visitor& visitor) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
   // When class is verified, set the kAccPreverified flag on each method.
   void SetPreverifiedFlagOnAllMethods() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
@@ -1079,6 +1091,10 @@
 
   void CheckObjectAlloc() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
+  // Unchecked editions is for root visiting.
+  ArtField* GetSFieldsUnchecked() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  ArtField* GetIFieldsUnchecked() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
   // defining class loader, or NULL for the "bootstrap" system loader
   HeapReference<ClassLoader> class_loader_;
 
@@ -1096,18 +1112,6 @@
   // static, private, and <init> methods
   HeapReference<ObjectArray<ArtMethod>> direct_methods_;
 
-  // instance fields
-  //
-  // These describe the layout of the contents of an Object.
-  // Note that only the fields directly declared by this class are
-  // listed in ifields; fields declared by a superclass are listed in
-  // the superclass's Class.ifields.
-  //
-  // All instance fields that refer to objects are guaranteed to be at
-  // the beginning of the field list.  num_reference_instance_fields_
-  // specifies the number of reference fields.
-  HeapReference<ObjectArray<ArtField>> ifields_;
-
   // The interface table (iftable_) contains pairs of a interface class and an array of the
   // interface methods. There is one pair per interface supported by this class.  That means one
   // pair for each interface we support directly, indirectly via superclass, or indirectly via a
@@ -1124,9 +1128,6 @@
   // Descriptor for the class such as "java.lang.Class" or "[C". Lazily initialized by ComputeName
   HeapReference<String> name_;
 
-  // Static fields
-  HeapReference<ObjectArray<ArtField>> sfields_;
-
   // The superclass, or NULL if this is java.lang.Object, an interface or primitive type.
   HeapReference<Class> super_class_;
 
@@ -1143,8 +1144,22 @@
   HeapReference<ObjectArray<ArtMethod>> vtable_;
 
   // Access flags; low 16 bits are defined by VM spec.
+  // Note: Shuffled back.
   uint32_t access_flags_;
 
+  // instance fields
+  //
+  // These describe the layout of the contents of an Object.
+  // Note that only the fields directly declared by this class are
+  // listed in ifields; fields declared by a superclass are listed in
+  // the superclass's Class.ifields.
+  //
+  // ArtField arrays are allocated as an array of fields, and not an array of fields pointers.
+  uint64_t ifields_;
+
+  // Static fields
+  uint64_t sfields_;
+
   // Total size of the Class instance; used when allocating storage on gc heap.
   // See also object_size_.
   uint32_t class_size_;
@@ -1160,12 +1175,18 @@
   // TODO: really 16bits
   int32_t dex_type_idx_;
 
+  // Number of static fields.
+  uint32_t num_instance_fields_;
+
   // Number of instance fields that are object refs.
   uint32_t num_reference_instance_fields_;
 
   // Number of static fields that are object refs,
   uint32_t num_reference_static_fields_;
 
+  // Number of static fields.
+  uint32_t num_static_fields_;
+
   // Total object size; used when allocating storage on gc heap.
   // (For interfaces and abstract classes this will be zero.)
   // See also class_size_.
diff --git a/runtime/mirror/dex_cache-inl.h b/runtime/mirror/dex_cache-inl.h
index 6758e22..1cb437e 100644
--- a/runtime/mirror/dex_cache-inl.h
+++ b/runtime/mirror/dex_cache-inl.h
@@ -19,6 +19,7 @@
 
 #include "dex_cache.h"
 
+#include "art_field-inl.h"
 #include "base/logging.h"
 #include "mirror/class.h"
 #include "runtime.h"
@@ -35,12 +36,11 @@
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   ArtMethod* method = GetResolvedMethods()->Get(method_idx);
   // Hide resolution trampoline methods from the caller
-  if (method != NULL && method->IsRuntimeMethod()) {
-    DCHECK(method == Runtime::Current()->GetResolutionMethod());
-    return NULL;
-  } else {
-    return method;
+  if (method != nullptr && method->IsRuntimeMethod()) {
+    DCHECK_EQ(method, Runtime::Current()->GetResolutionMethod());
+    return nullptr;
   }
+  return method;
 }
 
 inline void DexCache::SetResolvedType(uint32_t type_idx, Class* resolved) {
@@ -49,6 +49,34 @@
   GetResolvedTypes()->Set(type_idx, resolved);
 }
 
+inline ArtField* DexCache::GetResolvedField(uint32_t idx, size_t ptr_size) {
+  ArtField* field = nullptr;
+  if (ptr_size == 8) {
+    field = reinterpret_cast<ArtField*>(
+        static_cast<uintptr_t>(GetResolvedFields()->AsLongArray()->GetWithoutChecks(idx)));
+  } else {
+    DCHECK_EQ(ptr_size, 4u);
+    field = reinterpret_cast<ArtField*>(
+      static_cast<uintptr_t>(GetResolvedFields()->AsIntArray()->GetWithoutChecks(idx)));
+  }
+  if (field == nullptr || field->GetDeclaringClass()->IsErroneous()) {
+    return nullptr;
+  }
+  return field;
+}
+
+inline void DexCache::SetResolvedField(uint32_t idx, ArtField* field, size_t ptr_size) {
+  if (ptr_size == 8) {
+    GetResolvedFields()->AsLongArray()->Set(
+        idx, static_cast<uint64_t>(reinterpret_cast<uintptr_t>(field)));
+  } else {
+    DCHECK_EQ(ptr_size, 4u);
+    CHECK_LE(reinterpret_cast<uintptr_t>(field), 0xFFFFFFFF);
+    GetResolvedFields()->AsIntArray()->Set(
+        idx, static_cast<uint32_t>(reinterpret_cast<uintptr_t>(field)));
+  }
+}
+
 }  // namespace mirror
 }  // namespace art
 
diff --git a/runtime/mirror/dex_cache.cc b/runtime/mirror/dex_cache.cc
index d6c11e8..ade8bd2 100644
--- a/runtime/mirror/dex_cache.cc
+++ b/runtime/mirror/dex_cache.cc
@@ -36,7 +36,7 @@
                     ObjectArray<String>* strings,
                     ObjectArray<Class>* resolved_types,
                     ObjectArray<ArtMethod>* resolved_methods,
-                    ObjectArray<ArtField>* resolved_fields) {
+                    Array* resolved_fields) {
   CHECK(dex_file != nullptr);
   CHECK(location != nullptr);
   CHECK(strings != nullptr);
@@ -44,19 +44,18 @@
   CHECK(resolved_methods != nullptr);
   CHECK(resolved_fields != nullptr);
 
-  SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(DexCache, dex_file_), dex_file);
+  SetDexFile(dex_file);
   SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(DexCache, location_), location);
   SetFieldObject<false>(StringsOffset(), strings);
+  SetFieldObject<false>(ResolvedFieldsOffset(), resolved_fields);
   SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_types_), resolved_types);
   SetFieldObject<false>(ResolvedMethodsOffset(), resolved_methods);
-  SetFieldObject<false>(ResolvedFieldsOffset(), resolved_fields);
 
   Runtime* runtime = Runtime::Current();
   if (runtime->HasResolutionMethod()) {
     // Initialize the resolve methods array to contain trampolines for resolution.
     ArtMethod* trampoline = runtime->GetResolutionMethod();
-    size_t length = resolved_methods->GetLength();
-    for (size_t i = 0; i < length; i++) {
+    for (size_t i = 0, length = resolved_methods->GetLength(); i < length; i++) {
       resolved_methods->SetWithoutChecks<false>(i, trampoline);
     }
   }
diff --git a/runtime/mirror/dex_cache.h b/runtime/mirror/dex_cache.h
index c548c03..7e30b89 100644
--- a/runtime/mirror/dex_cache.h
+++ b/runtime/mirror/dex_cache.h
@@ -50,7 +50,7 @@
             ObjectArray<String>* strings,
             ObjectArray<Class>* types,
             ObjectArray<ArtMethod>* methods,
-            ObjectArray<ArtField>* fields)
+            Array* fields)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   void Fixup(ArtMethod* trampoline) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -116,23 +116,16 @@
     GetResolvedMethods()->Set(method_idx, resolved);
   }
 
-  ArtField* GetResolvedField(uint32_t field_idx) ALWAYS_INLINE
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    ArtField* field = GetResolvedFields()->Get(field_idx);
-    if (UNLIKELY(field == nullptr || field->GetDeclaringClass()->IsErroneous())) {
-      return nullptr;
-    } else {
-      return field;
-    }
-  }
+  // Pointer sized variant, used for patching.
+  ArtField* GetResolvedField(uint32_t idx, size_t ptr_size)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-  void SetResolvedField(uint32_t field_idx, ArtField* resolved) ALWAYS_INLINE
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    GetResolvedFields()->Set(field_idx, resolved);
-  }
+  // Pointer sized variant, used for patching.
+  void SetResolvedField(uint32_t idx, ArtField* field, size_t ptr_size)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   ObjectArray<String>* GetStrings() ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return GetFieldObject< ObjectArray<String>>(StringsOffset());
+    return GetFieldObject<ObjectArray<String>>(StringsOffset());
   }
 
   ObjectArray<Class>* GetResolvedTypes() ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -145,9 +138,8 @@
     return GetFieldObject< ObjectArray<ArtMethod>>(ResolvedMethodsOffset());
   }
 
-  ObjectArray<ArtField>* GetResolvedFields() ALWAYS_INLINE
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-    return GetFieldObject<ObjectArray<ArtField>>(ResolvedFieldsOffset());
+  Array* GetResolvedFields() ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    return GetFieldObject<Array>(ResolvedFieldsOffset());
   }
 
   const DexFile* GetDexFile() ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -162,7 +154,8 @@
  private:
   HeapReference<Object> dex_;
   HeapReference<String> location_;
-  HeapReference<ObjectArray<ArtField>> resolved_fields_;
+  // Either an int array or long array (64 bit).
+  HeapReference<Object> resolved_fields_;
   HeapReference<ObjectArray<ArtMethod>> resolved_methods_;
   HeapReference<ObjectArray<Class>> resolved_types_;
   HeapReference<ObjectArray<String>> strings_;
diff --git a/runtime/mirror/dex_cache_test.cc b/runtime/mirror/dex_cache_test.cc
index 53e5534..1d6846b 100644
--- a/runtime/mirror/dex_cache_test.cc
+++ b/runtime/mirror/dex_cache_test.cc
@@ -47,7 +47,7 @@
   EXPECT_LE(0, dex_cache->GetStrings()->GetLength());
   EXPECT_LE(0, dex_cache->GetResolvedTypes()->GetLength());
   EXPECT_LE(0, dex_cache->GetResolvedMethods()->GetLength());
-  EXPECT_LE(0, dex_cache->GetResolvedFields()->GetLength());
+  EXPECT_LE(0u, dex_cache->NumResolvedFields());
 
   EXPECT_EQ(java_lang_dex_file_->NumStringIds(),
             static_cast<uint32_t>(dex_cache->GetStrings()->GetLength()));
@@ -55,8 +55,7 @@
             static_cast<uint32_t>(dex_cache->GetResolvedTypes()->GetLength()));
   EXPECT_EQ(java_lang_dex_file_->NumMethodIds(),
             static_cast<uint32_t>(dex_cache->GetResolvedMethods()->GetLength()));
-  EXPECT_EQ(java_lang_dex_file_->NumFieldIds(),
-            static_cast<uint32_t>(dex_cache->GetResolvedFields()->GetLength()));
+  EXPECT_EQ(java_lang_dex_file_->NumFieldIds(), dex_cache->NumResolvedFields());
 }
 
 }  // namespace mirror
diff --git a/runtime/mirror/field-inl.h b/runtime/mirror/field-inl.h
index 24ebc48..7db1811 100644
--- a/runtime/mirror/field-inl.h
+++ b/runtime/mirror/field-inl.h
@@ -27,9 +27,8 @@
 namespace mirror {
 
 template <bool kTransactionActive>
-inline mirror::Field* Field::CreateFromArtField(Thread* self, mirror::ArtField* field,
+inline mirror::Field* Field::CreateFromArtField(Thread* self, ArtField* field,
                                                 bool force_resolve) {
-  CHECK(!kMovingFields);
   // Try to resolve type before allocating since this is a thread suspension point.
   mirror::Class* type = field->GetType<true>();
 
@@ -57,13 +56,13 @@
     return nullptr;
   }
   auto dex_field_index = field->GetDexFieldIndex();
-  auto* resolved_field = field->GetDexCache()->GetResolvedField(dex_field_index);
+  auto* resolved_field = field->GetDexCache()->GetResolvedField(dex_field_index, sizeof(void*));
   if (resolved_field != nullptr) {
     DCHECK_EQ(resolved_field, field);
   } else {
     // We rely on the field being resolved so that we can back to the ArtField
     // (i.e. FromReflectedMethod).
-    field->GetDexCache()->SetResolvedField(dex_field_index, field);
+    field->GetDexCache()->SetResolvedField(dex_field_index, field, sizeof(void*));
   }
   ret->SetType<kTransactionActive>(type);
   ret->SetDeclaringClass<kTransactionActive>(field->GetDeclaringClass());
diff --git a/runtime/mirror/field.cc b/runtime/mirror/field.cc
index 82cc26e..70311bb 100644
--- a/runtime/mirror/field.cc
+++ b/runtime/mirror/field.cc
@@ -55,7 +55,7 @@
 
 ArtField* Field::GetArtField() {
   mirror::DexCache* const dex_cache = GetDeclaringClass()->GetDexCache();
-  mirror::ArtField* const art_field = dex_cache->GetResolvedField(GetDexFieldIndex());
+  ArtField* const art_field = dex_cache->GetResolvedField(GetDexFieldIndex(), sizeof(void*));
   CHECK(art_field != nullptr);
   return art_field;
 }
diff --git a/runtime/mirror/field.h b/runtime/mirror/field.h
index cea06f5..9988f84 100644
--- a/runtime/mirror/field.h
+++ b/runtime/mirror/field.h
@@ -25,11 +25,11 @@
 
 namespace art {
 
+class ArtField;
 struct FieldOffsets;
 
 namespace mirror {
 
-class ArtField;
 class Class;
 class String;
 
@@ -93,10 +93,10 @@
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   // Slow, try to use only for PrettyField and such.
-  mirror::ArtField* GetArtField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  ArtField* GetArtField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   template <bool kTransactionActive = false>
-  static mirror::Field* CreateFromArtField(Thread* self, mirror::ArtField* field,
+  static mirror::Field* CreateFromArtField(Thread* self, ArtField* field,
                                            bool force_resolve)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h
index d690163..af0e856 100644
--- a/runtime/mirror/object-inl.h
+++ b/runtime/mirror/object-inl.h
@@ -225,18 +225,6 @@
 }
 
 template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
-inline bool Object::IsArtField() {
-  return GetClass<kVerifyFlags, kReadBarrierOption>()->
-      template IsArtFieldClass<kReadBarrierOption>();
-}
-
-template<VerifyObjectFlags kVerifyFlags>
-inline ArtField* Object::AsArtField() {
-  DCHECK(IsArtField<kVerifyFlags>());
-  return down_cast<ArtField*>(this);
-}
-
-template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
 inline bool Object::IsArtMethod() {
   return GetClass<kVerifyFlags, kReadBarrierOption>()->
       template IsArtMethodClass<kReadBarrierOption>();
@@ -318,8 +306,8 @@
 template<VerifyObjectFlags kVerifyFlags>
 inline IntArray* Object::AsIntArray() {
   constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
-  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
-  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveInt() ||
+  CHECK(GetClass<kVerifyFlags>()->IsArrayClass());
+  CHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveInt() ||
          GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveFloat());
   return down_cast<IntArray*>(this);
 }
@@ -327,8 +315,8 @@
 template<VerifyObjectFlags kVerifyFlags>
 inline LongArray* Object::AsLongArray() {
   constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
-  DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
-  DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveLong() ||
+  CHECK(GetClass<kVerifyFlags>()->IsArrayClass());
+  CHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveLong() ||
          GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveDouble());
   return down_cast<LongArray*>(this);
 }
@@ -403,7 +391,6 @@
   }
   DCHECK_GE(result, sizeof(Object))
       << " class=" << PrettyTypeOf(GetClass<kNewFlags, kReadBarrierOption>());
-  DCHECK(!(IsArtField<kNewFlags, kReadBarrierOption>()) || result == sizeof(ArtField));
   return result;
 }
 
diff --git a/runtime/mirror/object.cc b/runtime/mirror/object.cc
index 57ac46f..04d0cd8 100644
--- a/runtime/mirror/object.cc
+++ b/runtime/mirror/object.cc
@@ -204,22 +204,19 @@
     return;
   }
   for (Class* cur = c; cur != NULL; cur = cur->GetSuperClass()) {
-    ObjectArray<ArtField>* fields = cur->GetIFields();
-    if (fields != NULL) {
-      size_t num_ifields = fields->GetLength();
-      for (size_t i = 0; i < num_ifields; ++i) {
-        StackHandleScope<1> hs(Thread::Current());
-        Handle<Object> h_object(hs.NewHandle(new_value));
-        ArtField* field = fields->Get(i);
-        if (field->GetOffset().Int32Value() == field_offset.Int32Value()) {
-          CHECK_NE(field->GetTypeAsPrimitiveType(), Primitive::kPrimNot);
-          // TODO: resolve the field type for moving GC.
-          mirror::Class* field_type = field->GetType<!kMovingCollector>();
-          if (field_type != nullptr) {
-            CHECK(field_type->IsAssignableFrom(new_value->GetClass()));
-          }
-          return;
+    ArtField* fields = cur->GetIFields();
+    for (size_t i = 0, count = cur->NumInstanceFields(); i < count; ++i) {
+      StackHandleScope<1> hs(Thread::Current());
+      Handle<Object> h_object(hs.NewHandle(new_value));
+      ArtField* field = &fields[i];
+      if (field->GetOffset().Int32Value() == field_offset.Int32Value()) {
+        CHECK_NE(field->GetTypeAsPrimitiveType(), Primitive::kPrimNot);
+        // TODO: resolve the field type for moving GC.
+        mirror::Class* field_type = field->GetType<!kMovingCollector>();
+        if (field_type != nullptr) {
+          CHECK(field_type->IsAssignableFrom(new_value->GetClass()));
         }
+        return;
       }
     }
   }
@@ -228,20 +225,17 @@
     return;
   }
   if (IsClass()) {
-    ObjectArray<ArtField>* fields = AsClass()->GetSFields();
-    if (fields != NULL) {
-      size_t num_sfields = fields->GetLength();
-      for (size_t i = 0; i < num_sfields; ++i) {
-        ArtField* field = fields->Get(i);
-        if (field->GetOffset().Int32Value() == field_offset.Int32Value()) {
-          CHECK_NE(field->GetTypeAsPrimitiveType(), Primitive::kPrimNot);
-          // TODO: resolve the field type for moving GC.
-          mirror::Class* field_type = field->GetType<!kMovingCollector>();
-          if (field_type != nullptr) {
-            CHECK(field_type->IsAssignableFrom(new_value->GetClass()));
-          }
-          return;
+    ArtField* fields = AsClass()->GetSFields();
+    for (size_t i = 0, count = AsClass()->NumStaticFields(); i < count; ++i) {
+      ArtField* field = &fields[i];
+      if (field->GetOffset().Int32Value() == field_offset.Int32Value()) {
+        CHECK_NE(field->GetTypeAsPrimitiveType(), Primitive::kPrimNot);
+        // TODO: resolve the field type for moving GC.
+        mirror::Class* field_type = field->GetType<!kMovingCollector>();
+        if (field_type != nullptr) {
+          CHECK(field_type->IsAssignableFrom(new_value->GetClass()));
         }
+        return;
       }
     }
   }
diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h
index cfc8549..bfd5d4d 100644
--- a/runtime/mirror/object.h
+++ b/runtime/mirror/object.h
@@ -24,6 +24,7 @@
 
 namespace art {
 
+class ArtField;
 class ImageWriter;
 class LockWord;
 class Monitor;
@@ -33,7 +34,6 @@
 
 namespace mirror {
 
-class ArtField;
 class ArtMethod;
 class Array;
 class Class;
@@ -191,12 +191,6 @@
   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
   ArtMethod* AsArtMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-  template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
-           ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
-  bool IsArtField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-  template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
-  ArtField* AsArtField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
   bool IsReferenceInstance() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
diff --git a/runtime/mirror/object_array-inl.h b/runtime/mirror/object_array-inl.h
index 80d5135..30bc1cd 100644
--- a/runtime/mirror/object_array-inl.h
+++ b/runtime/mirror/object_array-inl.h
@@ -22,7 +22,6 @@
 #include "array-inl.h"
 #include "base/stringprintf.h"
 #include "gc/heap.h"
-#include "mirror/art_field.h"
 #include "mirror/class.h"
 #include "runtime.h"
 #include "handle_scope-inl.h"
@@ -36,13 +35,13 @@
 inline ObjectArray<T>* ObjectArray<T>::Alloc(Thread* self, Class* object_array_class,
                                              int32_t length, gc::AllocatorType allocator_type) {
   Array* array = Array::Alloc<true>(self, object_array_class, length,
-                                    ComponentSizeShiftWidth<sizeof(HeapReference<Object>)>(),
+                                    ComponentSizeShiftWidth(sizeof(HeapReference<Object>)),
                                     allocator_type);
   if (UNLIKELY(array == nullptr)) {
     return nullptr;
   } else {
     DCHECK_EQ(array->GetClass()->GetComponentSizeShift(),
-              ComponentSizeShiftWidth<sizeof(HeapReference<Object>)>());
+              ComponentSizeShiftWidth(sizeof(HeapReference<Object>)));
     return array->AsObjectArray<T>();
   }
 }
diff --git a/runtime/mirror/object_test.cc b/runtime/mirror/object_test.cc
index 1ce298d..747a008 100644
--- a/runtime/mirror/object_test.cc
+++ b/runtime/mirror/object_test.cc
@@ -722,14 +722,12 @@
                                      "Ljava/util/Comparator;") == NULL);
 
   // Right name and type.
-  Handle<ArtField> f1(hs.NewHandle(
-      c->FindDeclaredStaticField("CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;")));
-  Handle<ArtField> f2(hs.NewHandle(
-      mirror::Class::FindStaticField(soa.Self(), c, "CASE_INSENSITIVE_ORDER",
-                                     "Ljava/util/Comparator;")));
-  EXPECT_TRUE(f1.Get() != NULL);
-  EXPECT_TRUE(f2.Get() != NULL);
-  EXPECT_EQ(f1.Get(), f2.Get());
+  ArtField* f1 = c->FindDeclaredStaticField("CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
+  ArtField* f2 = mirror::Class::FindStaticField(soa.Self(), c, "CASE_INSENSITIVE_ORDER",
+                                                "Ljava/util/Comparator;");
+  EXPECT_TRUE(f1 != NULL);
+  EXPECT_TRUE(f2 != NULL);
+  EXPECT_EQ(f1, f2);
 
   // TODO: test static fields via superclasses.
   // TODO: test static fields via interfaces.