From d3c5bebcb52a67cb06e7ab303eaf45f230c08b60 Mon Sep 17 00:00:00 2001 From: Vladimir Marko Date: Fri, 11 Apr 2014 16:32:51 +0100 Subject: [PATCH] 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 --- compiler/oat_test.cc | 10 +++---- oatdump/oatdump.cc | 22 +++++++------- runtime/base/bit_vector.cc | 47 +++++++++++++++-------------- runtime/base/bit_vector.h | 9 +++++- runtime/base/bit_vector_test.cc | 28 ++++++++--------- runtime/class_linker.cc | 66 ++++++++++++++++++++--------------------- runtime/class_linker.h | 8 ++++- runtime/oat_file.cc | 32 ++++++++------------ runtime/oat_file.h | 11 +++---- 9 files changed, 117 insertions(+), 116 deletions(-) diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc index 9cfef12b2..766ef7b13 100644 --- a/compiler/oat_test.cc +++ b/compiler/oat_test.cc @@ -155,19 +155,19 @@ TEST_F(OatTest, WriteRead) { SirtRef loader(soa.Self(), nullptr); mirror::Class* klass = class_linker->FindClass(soa.Self(), descriptor, loader); - UniquePtr 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 915c415c6..3c07f56cb 100644 --- a/oatdump/oatdump.cc +++ b/oatdump/oatdump.cc @@ -215,10 +215,9 @@ class OatDumper { 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 OatDumper { class_def_index < dex_file->NumClassDefs(); class_def_index++) { const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_index); - UniquePtr 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 OatDumper { class_def_index++) { const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_index); const char* descriptor = dex_file->GetClassDescriptor(class_def); - UniquePtr 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 590835e05..d8ef96252 100644 --- a/runtime/base/bit_vector.cc +++ b/runtime/base/bit_vector.cc @@ -65,8 +65,7 @@ bool BitVector::IsBitSet(uint32_t num) const { 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 @@ uint32_t BitVector::NumSetBits() const { 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 @@ void BitVector::Copy(const BitVector *src) { } } +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 c8f285e87..a496dbd4d 100644 --- a/runtime/base/bit_vector.h +++ b/runtime/base/bit_vector.h @@ -119,7 +119,9 @@ class BitVector { 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 @@ class BitVector { */ 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 a67fb332b..2ff55cbb3 100644 --- a/runtime/base/bit_vector_test.cc +++ b/runtime/base/bit_vector_test.cc @@ -29,8 +29,8 @@ TEST(BitVector, Test) { 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 @@ TEST(BitVector, Test) { 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 @@ TEST(BitVector, NoopAllocator) { 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 e690b3078..d89ba5591 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -1523,7 +1523,7 @@ uint32_t ClassLinker::SizeOfClass(const DexFile& dex_file, 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::OatClass* ClassLinker::GetOatClass(const DexFile& dex_file, uint1 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 @@ const OatFile::OatMethod ClassLinker::GetOatMethodFor(mirror::ArtMethod* method) } CHECK(found) << "Didn't find oat method index for virtual method: " << PrettyMethod(method); } - UniquePtr - 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::GetPortableOatCodeFor(mirror::ArtMethod* method, const void* ClassLinker::GetQuickOatCodeFor(const DexFile& dex_file, uint16_t class_def_idx, uint32_t method_idx) { - UniquePtr 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 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 @@ void ClassLinker::FixupStaticTrampolines(mirror::Class* klass) { 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 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 @@ void ClassLinker::FixupStaticTrampolines(mirror::Class* klass) { // 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 @@ void ClassLinker::LoadClass(const DexFile& dex_file, 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& 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 @@ void ClassLinker::LoadClass(const DexFile& dex_file, LoadField(dex_file, it, klass, ifield); } - UniquePtr 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 @@ void ClassLinker::LoadClass(const DexFile& dex_file, 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 @@ void ClassLinker::LoadClass(const DexFile& dex_file, } 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 @@ bool ClassLinker::VerifyClassUsingOatFile(const DexFile& dex_file, mirror::Class &dex_location_checksum); CHECK(oat_dex_file != NULL) << dex_file.GetLocation() << " " << PrettyClass(klass); uint16_t class_def_index = klass->GetDexClassDefIndex(); - UniquePtr 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 d684ad568..a14d1d12e 100644 --- a/runtime/class_linker.h +++ b/runtime/class_linker.h @@ -433,6 +433,12 @@ class ClassLinker { const SirtRef& klass, mirror::ClassLoader* class_loader) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + void LoadClassMembers(const DexFile& dex_file, + const byte* class_data, + const SirtRef& 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& klass, const SirtRef& dst) @@ -446,7 +452,7 @@ class ClassLinker { 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& dex_cache) diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc index 1967345c7..0aff8c300 100644 --- a/runtime/oat_file.cc +++ b/runtime/oat_file.cc @@ -386,7 +386,7 @@ const DexFile* OatFile::OatDexFile::OpenDexFile(std::string* error_msg) const { 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 @@ const OatFile::OatClass* OatFile::OatDexFile::GetOatClass(uint16_t class_def_ind } CHECK_LE(methods_pointer, oat_file_->End()) << oat_file_->GetLocation(); - return new OatClass(oat_file_, - status, - type, - bitmap_size, - reinterpret_cast(bitmap_pointer), - reinterpret_cast(methods_pointer)); + return OatClass(oat_file_, + status, + type, + bitmap_size, + reinterpret_cast(bitmap_pointer), + reinterpret_cast(methods_pointer)); } OatFile::OatClass::OatClass(const OatFile* oat_file, @@ -434,7 +434,7 @@ OatFile::OatClass::OatClass(const OatFile* oat_file, 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 @@ OatFile::OatClass::OatClass(const OatFile* oat_file, case kOatClassSomeCompiled: { CHECK_NE(0U, bitmap_size); CHECK(bitmap_pointer != nullptr); - bitmap_ = new BitVector(0, false, Allocator::GetNoopAllocator(), bitmap_size, - const_cast(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(const OatFile* oat_file, } } -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 @@ const OatFile::OatMethod OatFile::OatClass::GetOatMethod(uint32_t method_index) 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 d6e8dc07f..10f64cc91 100644 --- a/runtime/oat_file.h +++ b/runtime/oat_file.h @@ -181,7 +181,6 @@ class OatFile { // 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 @@ class OatFile { 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 @@ class OatFile { } // 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(); -- 2.11.0