Avoid allocating OatFile::OatClass on the heap.

Avoid allocating a BitVector for OatFile::OatClass::bitmap_
with kOatClassSomeCompiled methods. That makes the OatClass
copy-constructible as it doesn't own any memory. We use that
in OatFile::OatDexFile::GetOatClass() to return the result
by value thus avoiding one or two heap allocations per call.

Change-Id: Ic7098109028a5b49e39ef626f877de86e732ed18
diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc
index 9cfef12..766ef7b 100644
--- a/compiler/oat_test.cc
+++ b/compiler/oat_test.cc
@@ -155,19 +155,19 @@
     SirtRef<mirror::ClassLoader> loader(soa.Self(), nullptr);
     mirror::Class* klass = class_linker->FindClass(soa.Self(), descriptor, loader);
 
-    UniquePtr<const OatFile::OatClass> oat_class(oat_dex_file->GetOatClass(i));
-    CHECK_EQ(mirror::Class::Status::kStatusNotReady, oat_class->GetStatus()) << descriptor;
+    const OatFile::OatClass oat_class = oat_dex_file->GetOatClass(i);
+    CHECK_EQ(mirror::Class::Status::kStatusNotReady, oat_class.GetStatus()) << descriptor;
     CHECK_EQ(kCompile ? OatClassType::kOatClassAllCompiled : OatClassType::kOatClassNoneCompiled,
-             oat_class->GetType()) << descriptor;
+             oat_class.GetType()) << descriptor;
 
     size_t method_index = 0;
     for (size_t i = 0; i < klass->NumDirectMethods(); i++, method_index++) {
       CheckMethod(klass->GetDirectMethod(i),
-                  oat_class->GetOatMethod(method_index), dex_file);
+                  oat_class.GetOatMethod(method_index), dex_file);
     }
     for (size_t i = 0; i < num_virtual_methods; i++, method_index++) {
       CheckMethod(klass->GetVirtualMethod(i),
-                  oat_class->GetOatMethod(method_index), dex_file);
+                  oat_class.GetOatMethod(method_index), dex_file);
     }
   }
 }
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index 915c415..3c07f56 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -215,10 +215,9 @@
             dex_file->FindClassDef(mh.GetDeclaringClassDescriptor());
         if (class_def != NULL) {
           uint16_t class_def_index = dex_file->GetIndexForClassDef(*class_def);
-          const OatFile::OatClass* oat_class = oat_dex_file->GetOatClass(class_def_index);
-          CHECK(oat_class != NULL);
+          const OatFile::OatClass oat_class = oat_dex_file->GetOatClass(class_def_index);
           size_t method_index = m->GetMethodIndex();
-          return oat_class->GetOatMethod(method_index).GetQuickCode();
+          return oat_class.GetOatMethod(method_index).GetQuickCode();
         }
       }
     }
@@ -246,18 +245,18 @@
            class_def_index < dex_file->NumClassDefs();
            class_def_index++) {
         const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_index);
-        UniquePtr<const OatFile::OatClass> oat_class(oat_dex_file->GetOatClass(class_def_index));
+        const OatFile::OatClass oat_class = oat_dex_file->GetOatClass(class_def_index);
         const byte* class_data = dex_file->GetClassData(class_def);
         if (class_data != NULL) {
           ClassDataItemIterator it(*dex_file, class_data);
           SkipAllFields(it);
           uint32_t class_method_index = 0;
           while (it.HasNextDirectMethod()) {
-            AddOffsets(oat_class->GetOatMethod(class_method_index++));
+            AddOffsets(oat_class.GetOatMethod(class_method_index++));
             it.Next();
           }
           while (it.HasNextVirtualMethod()) {
-            AddOffsets(oat_class->GetOatMethod(class_method_index++));
+            AddOffsets(oat_class.GetOatMethod(class_method_index++));
             it.Next();
           }
         }
@@ -299,15 +298,14 @@
          class_def_index++) {
       const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_index);
       const char* descriptor = dex_file->GetClassDescriptor(class_def);
-      UniquePtr<const OatFile::OatClass> oat_class(oat_dex_file.GetOatClass(class_def_index));
-      CHECK(oat_class.get() != NULL);
+      const OatFile::OatClass oat_class = oat_dex_file.GetOatClass(class_def_index);
       os << StringPrintf("%zd: %s (type_idx=%d)", class_def_index, descriptor, class_def.class_idx_)
-         << " (" << oat_class->GetStatus() << ")"
-         << " (" << oat_class->GetType() << ")\n";
-      // TODO: include bitmap here if type is kOatClassBitmap?
+         << " (" << oat_class.GetStatus() << ")"
+         << " (" << oat_class.GetType() << ")\n";
+      // TODO: include bitmap here if type is kOatClassSomeCompiled?
       Indenter indent_filter(os.rdbuf(), kIndentChar, kIndentBy1Count);
       std::ostream indented_os(&indent_filter);
-      DumpOatClass(indented_os, *oat_class.get(), *(dex_file.get()), class_def);
+      DumpOatClass(indented_os, oat_class, *(dex_file.get()), class_def);
     }
 
     os << std::flush;
diff --git a/runtime/base/bit_vector.cc b/runtime/base/bit_vector.cc
index 590835e..d8ef962 100644
--- a/runtime/base/bit_vector.cc
+++ b/runtime/base/bit_vector.cc
@@ -65,8 +65,7 @@
     return false;
   }
 
-  uint32_t val = storage_[num >> 5] & check_masks[num & 0x1f];
-  return (val != 0);
+  return IsBitSet(storage_, num);
 }
 
 // Mark all bits bit as "clear".
@@ -213,27 +212,10 @@
   return count;
 }
 
-// Count the number of bits that are set up through and including num.
-uint32_t BitVector::NumSetBits(uint32_t num) const {
-  DCHECK_LT(num, storage_size_ * sizeof(*storage_) * 8);
-  uint32_t last_word = num >> 5;
-  uint32_t partial_word_bits = num & 0x1f;
-
-  // partial_word_bits |  # |                         |                      | partial_word_mask
-  //             00000 |  0 | 0xffffffff >> (31 -  0) | (1 <<  (0 + 1)) - 1  | 0x00000001
-  //             00001 |  1 | 0xffffffff >> (31 -  1) | (1 <<  (1 + 1)) - 1  | 0x00000003
-  //             00010 |  2 | 0xffffffff >> (31 -  2) | (1 <<  (2 + 1)) - 1  | 0x00000007
-  //             ..... |
-  //             11110 | 30 | 0xffffffff >> (31 - 30) | (1 << (30 + 1)) - 1  | 0x7fffffff
-  //             11111 | 31 | 0xffffffff >> (31 - 31) | last_full_word++     | 0xffffffff
-  uint32_t partial_word_mask = 0xffffffff >> (0x1f - partial_word_bits);
-
-  uint32_t count = 0;
-  for (uint32_t word = 0; word < last_word; word++) {
-    count += __builtin_popcount(storage_[word]);
-  }
-  count += __builtin_popcount(storage_[last_word] & partial_word_mask);
-  return count;
+// Count the number of bits that are set in range [0, end).
+uint32_t BitVector::NumSetBits(uint32_t end) const {
+  DCHECK_LE(end, storage_size_ * sizeof(*storage_) * 8);
+  return NumSetBits(storage_, end);
 }
 
 BitVector::Iterator* BitVector::GetIterator() const {
@@ -327,4 +309,23 @@
   }
 }
 
+bool BitVector::IsBitSet(const uint32_t* storage, uint32_t num) {
+  uint32_t val = storage[num >> 5] & check_masks[num & 0x1f];
+  return (val != 0);
+}
+
+uint32_t BitVector::NumSetBits(const uint32_t* storage, uint32_t end) {
+  uint32_t word_end = end >> 5;
+  uint32_t partial_word_bits = end & 0x1f;
+
+  uint32_t count = 0u;
+  for (uint32_t word = 0u; word < word_end; word++) {
+    count += __builtin_popcount(storage[word]);
+  }
+  if (partial_word_bits != 0u) {
+    count += __builtin_popcount(storage[word_end] & ~(0xffffffffu << partial_word_bits));
+  }
+  return count;
+}
+
 }  // namespace art
diff --git a/runtime/base/bit_vector.h b/runtime/base/bit_vector.h
index c8f285e..a496dbd 100644
--- a/runtime/base/bit_vector.h
+++ b/runtime/base/bit_vector.h
@@ -119,7 +119,9 @@
     bool SameBitsSet(const BitVector *src);
 
     uint32_t NumSetBits() const;
-    uint32_t NumSetBits(uint32_t num) const;
+
+    // Number of bits set in range [0, end).
+    uint32_t NumSetBits(uint32_t end) const;
 
     Iterator* GetIterator() const;
 
@@ -135,6 +137,11 @@
      */
     int GetHighestBitSet() const;
 
+    // Is bit set in storage. (No range check.)
+    static bool IsBitSet(const uint32_t* storage, uint32_t num);
+    // Number of bits set in range [0, end) in storage. (No range check.)
+    static uint32_t NumSetBits(const uint32_t* storage, uint32_t end);
+
   private:
     Allocator* const allocator_;
     const bool expandable_;         // expand bitmap if we run out?
diff --git a/runtime/base/bit_vector_test.cc b/runtime/base/bit_vector_test.cc
index a67fb33..2ff55cb 100644
--- a/runtime/base/bit_vector_test.cc
+++ b/runtime/base/bit_vector_test.cc
@@ -29,8 +29,8 @@
   EXPECT_FALSE(bv.IsExpandable());
 
   EXPECT_EQ(0U, bv.NumSetBits());
-  EXPECT_EQ(0U, bv.NumSetBits(0));
-  EXPECT_EQ(0U, bv.NumSetBits(kBits - 1));
+  EXPECT_EQ(0U, bv.NumSetBits(1));
+  EXPECT_EQ(0U, bv.NumSetBits(kBits));
   for (size_t i = 0; i < kBits; i++) {
     EXPECT_FALSE(bv.IsBitSet(i));
   }
@@ -46,8 +46,8 @@
   bv.SetBit(0);
   bv.SetBit(kBits - 1);
   EXPECT_EQ(2U, bv.NumSetBits());
-  EXPECT_EQ(1U, bv.NumSetBits(0));
-  EXPECT_EQ(2U, bv.NumSetBits(kBits - 1));
+  EXPECT_EQ(1U, bv.NumSetBits(1));
+  EXPECT_EQ(2U, bv.NumSetBits(kBits));
   EXPECT_TRUE(bv.IsBitSet(0));
   for (size_t i = 1; i < kBits - 1; i++) {
     EXPECT_FALSE(bv.IsBitSet(i));
@@ -98,25 +98,25 @@
   EXPECT_EQ(0x00010001U, bv.GetRawStorageWord(1));
   EXPECT_EQ(4U, bv.NumSetBits());
 
-  EXPECT_EQ(0U, bv.NumSetBits(0));
+  EXPECT_EQ(0U, bv.NumSetBits(1));
 
-  EXPECT_EQ(0U, bv.NumSetBits(7));
-  EXPECT_EQ(1U, bv.NumSetBits(8));
+  EXPECT_EQ(0U, bv.NumSetBits(8));
   EXPECT_EQ(1U, bv.NumSetBits(9));
+  EXPECT_EQ(1U, bv.NumSetBits(10));
 
-  EXPECT_EQ(1U, bv.NumSetBits(15));
-  EXPECT_EQ(2U, bv.NumSetBits(16));
+  EXPECT_EQ(1U, bv.NumSetBits(16));
   EXPECT_EQ(2U, bv.NumSetBits(17));
+  EXPECT_EQ(2U, bv.NumSetBits(18));
 
-  EXPECT_EQ(2U, bv.NumSetBits(31));
-  EXPECT_EQ(3U, bv.NumSetBits(32));
+  EXPECT_EQ(2U, bv.NumSetBits(32));
   EXPECT_EQ(3U, bv.NumSetBits(33));
+  EXPECT_EQ(3U, bv.NumSetBits(34));
 
-  EXPECT_EQ(3U, bv.NumSetBits(47));
-  EXPECT_EQ(4U, bv.NumSetBits(48));
+  EXPECT_EQ(3U, bv.NumSetBits(48));
   EXPECT_EQ(4U, bv.NumSetBits(49));
+  EXPECT_EQ(4U, bv.NumSetBits(50));
 
-  EXPECT_EQ(4U, bv.NumSetBits(63));
+  EXPECT_EQ(4U, bv.NumSetBits(64));
 }
 
 TEST(BitVector, SetInitialBits) {
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index e690b30..d89ba55 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1523,7 +1523,7 @@
   return size;
 }
 
-const OatFile::OatClass* ClassLinker::GetOatClass(const DexFile& dex_file, uint16_t class_def_idx) {
+OatFile::OatClass ClassLinker::GetOatClass(const DexFile& dex_file, uint16_t class_def_idx) {
   DCHECK_NE(class_def_idx, DexFile::kDexNoIndex16);
   const OatFile* oat_file = FindOpenedOatFileForDexFile(dex_file);
   CHECK(oat_file != NULL) << dex_file.GetLocation();
@@ -1531,9 +1531,7 @@
   const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_file.GetLocation().c_str(),
                                                                     &dex_location_checksum);
   CHECK(oat_dex_file != NULL) << dex_file.GetLocation();
-  const OatFile::OatClass* oat_class = oat_dex_file->GetOatClass(class_def_idx);
-  CHECK(oat_class != NULL) << dex_file.GetLocation() << " " << class_def_idx;
-  return oat_class;
+  return oat_dex_file->GetOatClass(class_def_idx);
 }
 
 static uint32_t GetOatMethodIndexFromMethodIndex(const DexFile& dex_file, uint16_t class_def_idx,
@@ -1593,16 +1591,14 @@
     }
     CHECK(found) << "Didn't find oat method index for virtual method: " << PrettyMethod(method);
   }
-  UniquePtr<const OatFile::OatClass>
-      oat_class(GetOatClass(*declaring_class->GetDexCache()->GetDexFile(),
-                            declaring_class->GetDexClassDefIndex()));
-  CHECK(oat_class.get() != NULL);
   DCHECK_EQ(oat_method_index,
             GetOatMethodIndexFromMethodIndex(*declaring_class->GetDexCache()->GetDexFile(),
                                              method->GetDeclaringClass()->GetDexClassDefIndex(),
                                              method->GetDexMethodIndex()));
+  const OatFile::OatClass oat_class = GetOatClass(*declaring_class->GetDexCache()->GetDexFile(),
+                                                  declaring_class->GetDexClassDefIndex());
 
-  return oat_class->GetOatMethod(oat_method_index);
+  return oat_class.GetOatMethod(oat_method_index);
 }
 
 // Special case to get oat code without overwriting a trampoline.
@@ -1651,18 +1647,16 @@
 
 const void* ClassLinker::GetQuickOatCodeFor(const DexFile& dex_file, uint16_t class_def_idx,
                                             uint32_t method_idx) {
-  UniquePtr<const OatFile::OatClass> oat_class(GetOatClass(dex_file, class_def_idx));
-  CHECK(oat_class.get() != nullptr);
+  const OatFile::OatClass oat_class = GetOatClass(dex_file, class_def_idx);
   uint32_t oat_method_idx = GetOatMethodIndexFromMethodIndex(dex_file, class_def_idx, method_idx);
-  return oat_class->GetOatMethod(oat_method_idx).GetQuickCode();
+  return oat_class.GetOatMethod(oat_method_idx).GetQuickCode();
 }
 
 const void* ClassLinker::GetPortableOatCodeFor(const DexFile& dex_file, uint16_t class_def_idx,
                                                uint32_t method_idx) {
-  UniquePtr<const OatFile::OatClass> oat_class(GetOatClass(dex_file, class_def_idx));
-  CHECK(oat_class.get() != nullptr);
+  const OatFile::OatClass oat_class = GetOatClass(dex_file, class_def_idx);
   uint32_t oat_method_idx = GetOatMethodIndexFromMethodIndex(dex_file, class_def_idx, method_idx);
-  return oat_class->GetOatMethod(oat_method_idx).GetPortableCode();
+  return oat_class.GetOatMethod(oat_method_idx).GetPortableCode();
 }
 
 // Returns true if the method must run with interpreter, false otherwise.
@@ -1703,8 +1697,7 @@
   const byte* class_data = dex_file.GetClassData(*dex_class_def);
   // There should always be class data if there were direct methods.
   CHECK(class_data != nullptr) << PrettyDescriptor(klass);
-  UniquePtr<const OatFile::OatClass> oat_class(GetOatClass(dex_file, klass->GetDexClassDefIndex()));
-  CHECK(oat_class.get() != nullptr);
+  const OatFile::OatClass oat_class = GetOatClass(dex_file, klass->GetDexClassDefIndex());
   ClassDataItemIterator it(dex_file, class_data);
   // Skip fields
   while (it.HasNextStaticField()) {
@@ -1720,8 +1713,8 @@
       // Only update static methods.
       continue;
     }
-    const void* portable_code = oat_class->GetOatMethod(method_index).GetPortableCode();
-    const void* quick_code = oat_class->GetOatMethod(method_index).GetQuickCode();
+    const void* portable_code = oat_class.GetOatMethod(method_index).GetPortableCode();
+    const void* quick_code = oat_class.GetOatMethod(method_index).GetQuickCode();
     const bool enter_interpreter = NeedsInterpreter(method, quick_code, portable_code);
     bool have_portable_code = false;
     if (enter_interpreter) {
@@ -1869,11 +1862,25 @@
   klass->SetDexClassDefIndex(dex_file.GetIndexForClassDef(dex_class_def));
   klass->SetDexTypeIndex(dex_class_def.class_idx_);
 
-  // Load fields fields.
   const byte* class_data = dex_file.GetClassData(dex_class_def);
   if (class_data == NULL) {
     return;  // no fields or methods - for example a marker interface
   }
+
+  if (Runtime::Current()->IsStarted() && !Runtime::Current()->UseCompileTimeClassPath()) {
+    const OatFile::OatClass oat_class = GetOatClass(dex_file, klass->GetDexClassDefIndex());
+    LoadClassMembers(dex_file, class_data, klass, class_loader, &oat_class);
+  } else {
+    LoadClassMembers(dex_file, class_data, klass, class_loader, nullptr);
+  }
+}
+
+void ClassLinker::LoadClassMembers(const DexFile& dex_file,
+                                   const byte* class_data,
+                                   const SirtRef<mirror::Class>& klass,
+                                   mirror::ClassLoader* class_loader,
+                                   const OatFile::OatClass* oat_class) {
+  // Load fields.
   ClassDataItemIterator it(dex_file, class_data);
   Thread* self = Thread::Current();
   if (it.NumStaticFields() != 0) {
@@ -1912,11 +1919,6 @@
     LoadField(dex_file, it, klass, ifield);
   }
 
-  UniquePtr<const OatFile::OatClass> oat_class;
-  if (Runtime::Current()->IsStarted() && !Runtime::Current()->UseCompileTimeClassPath()) {
-    oat_class.reset(GetOatClass(dex_file, klass->GetDexClassDefIndex()));
-  }
-
   // Load methods.
   if (it.NumDirectMethods() != 0) {
     // TODO: append direct methods to class object
@@ -1946,8 +1948,8 @@
       return;
     }
     klass->SetDirectMethod(i, method.get());
-    if (oat_class.get() != NULL) {
-      LinkCode(method, oat_class.get(), dex_file, it.GetMemberIndex(), class_def_method_index);
+    if (oat_class != nullptr) {
+      LinkCode(method, oat_class, dex_file, it.GetMemberIndex(), class_def_method_index);
     }
     method->SetMethodIndex(class_def_method_index);
     class_def_method_index++;
@@ -1960,8 +1962,8 @@
     }
     klass->SetVirtualMethod(i, method.get());
     DCHECK_EQ(class_def_method_index, it.NumDirectMethods() + i);
-    if (oat_class.get() != NULL) {
-      LinkCode(method, oat_class.get(), dex_file, it.GetMemberIndex(), class_def_method_index);
+    if (oat_class != nullptr) {
+      LinkCode(method, oat_class, dex_file, it.GetMemberIndex(), class_def_method_index);
     }
     class_def_method_index++;
   }
@@ -2691,11 +2693,7 @@
                                                                     &dex_location_checksum);
   CHECK(oat_dex_file != NULL) << dex_file.GetLocation() << " " << PrettyClass(klass);
   uint16_t class_def_index = klass->GetDexClassDefIndex();
-  UniquePtr<const OatFile::OatClass> oat_class(oat_dex_file->GetOatClass(class_def_index));
-  CHECK(oat_class.get() != NULL)
-          << dex_file.GetLocation() << " " << PrettyClass(klass) << " "
-          << ClassHelper(klass).GetDescriptor();
-  oat_file_class_status = oat_class->GetStatus();
+  oat_file_class_status = oat_dex_file->GetOatClass(class_def_index).GetStatus();
   if (oat_file_class_status == mirror::Class::kStatusVerified ||
       oat_file_class_status == mirror::Class::kStatusInitialized) {
       return true;
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index d684ad5..a14d1d1 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -433,6 +433,12 @@
                  const SirtRef<mirror::Class>& klass,
                  mirror::ClassLoader* class_loader)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  void LoadClassMembers(const DexFile& dex_file,
+                        const byte* class_data,
+                        const SirtRef<mirror::Class>& klass,
+                        mirror::ClassLoader* class_loader,
+                        const OatFile::OatClass* oat_class)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   void LoadField(const DexFile& dex_file, const ClassDataItemIterator& it,
                  const SirtRef<mirror::Class>& klass, const SirtRef<mirror::ArtField>& dst)
@@ -446,7 +452,7 @@
   void FixupStaticTrampolines(mirror::Class* klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   // Finds the associated oat class for a dex_file and descriptor
-  const OatFile::OatClass* GetOatClass(const DexFile& dex_file, uint16_t class_def_idx)
+  OatFile::OatClass GetOatClass(const DexFile& dex_file, uint16_t class_def_idx)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   void RegisterDexFileLocked(const DexFile& dex_file, const SirtRef<mirror::DexCache>& dex_cache)
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index 1967345..0aff8c3 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -386,7 +386,7 @@
                        dex_file_location_checksum_, error_msg);
 }
 
-const OatFile::OatClass* OatFile::OatDexFile::GetOatClass(uint16_t class_def_index) const {
+OatFile::OatClass OatFile::OatDexFile::GetOatClass(uint16_t class_def_index) const {
   uint32_t oat_class_offset = oat_class_offsets_pointer_[class_def_index];
 
   const byte* oat_class_pointer = oat_file_->Begin() + oat_class_offset;
@@ -419,12 +419,12 @@
   }
   CHECK_LE(methods_pointer, oat_file_->End()) << oat_file_->GetLocation();
 
-  return new OatClass(oat_file_,
-                      status,
-                      type,
-                      bitmap_size,
-                      reinterpret_cast<const uint32_t*>(bitmap_pointer),
-                      reinterpret_cast<const OatMethodOffsets*>(methods_pointer));
+  return OatClass(oat_file_,
+                  status,
+                  type,
+                  bitmap_size,
+                  reinterpret_cast<const uint32_t*>(bitmap_pointer),
+                  reinterpret_cast<const OatMethodOffsets*>(methods_pointer));
 }
 
 OatFile::OatClass::OatClass(const OatFile* oat_file,
@@ -434,7 +434,7 @@
                             const uint32_t* bitmap_pointer,
                             const OatMethodOffsets* methods_pointer)
     : oat_file_(oat_file), status_(status), type_(type),
-      bitmap_(NULL), methods_pointer_(methods_pointer) {
+      bitmap_(bitmap_pointer), methods_pointer_(methods_pointer) {
     CHECK(methods_pointer != nullptr);
     switch (type_) {
       case kOatClassAllCompiled: {
@@ -445,14 +445,12 @@
       case kOatClassSomeCompiled: {
         CHECK_NE(0U, bitmap_size);
         CHECK(bitmap_pointer != nullptr);
-        bitmap_ = new BitVector(0, false, Allocator::GetNoopAllocator(), bitmap_size,
-                                const_cast<uint32_t*>(bitmap_pointer));
         break;
       }
       case kOatClassNoneCompiled: {
         CHECK_EQ(0U, bitmap_size);
         CHECK(bitmap_pointer == nullptr);
-        methods_pointer_ = NULL;
+        methods_pointer_ = nullptr;
         break;
       }
       case kOatClassMax: {
@@ -462,11 +460,8 @@
     }
 }
 
-OatFile::OatClass::~OatClass() {
-  delete bitmap_;
-}
-
 const OatFile::OatMethod OatFile::OatClass::GetOatMethod(uint32_t method_index) const {
+  // NOTE: We don't keep the number of methods and cannot do a bounds check for method_index.
   if (methods_pointer_ == NULL) {
     CHECK_EQ(kOatClassNoneCompiled, type_);
     return OatMethod(NULL, 0, 0, 0, 0, 0, 0, 0);
@@ -477,12 +472,11 @@
     methods_pointer_index = method_index;
   } else {
     CHECK_EQ(kOatClassSomeCompiled, type_);
-    if (!bitmap_->IsBitSet(method_index)) {
+    if (!BitVector::IsBitSet(bitmap_, method_index)) {
       return OatMethod(NULL, 0, 0, 0, 0, 0, 0, 0);
     }
-    size_t num_set_bits = bitmap_->NumSetBits(method_index);
-    CHECK_NE(0U, num_set_bits);
-    methods_pointer_index = num_set_bits - 1;
+    size_t num_set_bits = BitVector::NumSetBits(bitmap_, method_index);
+    methods_pointer_index = num_set_bits;
   }
   const OatMethodOffsets& oat_method_offsets = methods_pointer_[methods_pointer_index];
   return OatMethod(
diff --git a/runtime/oat_file.h b/runtime/oat_file.h
index d6e8dc0..10f64cc 100644
--- a/runtime/oat_file.h
+++ b/runtime/oat_file.h
@@ -181,7 +181,6 @@
     // methods. note that runtime created methods such as miranda
     // methods are not included.
     const OatMethod GetOatMethod(uint32_t method_index) const;
-    ~OatClass();
 
    private:
     OatClass(const OatFile* oat_file,
@@ -191,15 +190,13 @@
              const uint32_t* bitmap_pointer,
              const OatMethodOffsets* methods_pointer);
 
-    const OatFile* oat_file_;
+    const OatFile* const oat_file_;
 
     const mirror::Class::Status status_;
-    COMPILE_ASSERT(mirror::Class::Status::kStatusMax < (2 ^ 16), class_status_wont_fit_in_16bits);
 
-    OatClassType type_;
-    COMPILE_ASSERT(OatClassType::kOatClassMax < (2 ^ 16), oat_class_type_wont_fit_in_16bits);
+    const OatClassType type_;
 
-    const BitVector* bitmap_;
+    const uint32_t* const bitmap_;
 
     const OatMethodOffsets* methods_pointer_;
 
@@ -225,7 +222,7 @@
     }
 
     // Returns the OatClass for the class specified by the given DexFile class_def_index.
-    const OatClass* GetOatClass(uint16_t class_def_index) const;
+    OatClass GetOatClass(uint16_t class_def_index) const;
 
     ~OatDexFile();