summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler/oat_test.cc10
-rw-r--r--oatdump/oatdump.cc22
-rw-r--r--runtime/base/bit_vector.cc47
-rw-r--r--runtime/base/bit_vector.h9
-rw-r--r--runtime/base/bit_vector_test.cc28
-rw-r--r--runtime/class_linker.cc66
-rw-r--r--runtime/class_linker.h8
-rw-r--r--runtime/oat_file.cc32
-rw-r--r--runtime/oat_file.h11
9 files changed, 117 insertions, 116 deletions
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 @@ TEST_F(OatTest, WriteRead) {
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 c191226..5054f96 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<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 OatDumper {
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 @@ 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 c8f285e..a496dbd 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 a67fb33..2ff55cb 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 9ca0b78..58b82f0 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<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.
@@ -1652,18 +1648,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<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.
@@ -1704,8 +1698,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<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()) {
@@ -1721,8 +1714,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) {
@@ -1870,11 +1863,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<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) {
@@ -1913,11 +1920,6 @@ void ClassLinker::LoadClass(const DexFile& dex_file,
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
@@ -1947,8 +1949,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++;
@@ -1961,8 +1963,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++;
}
@@ -2692,11 +2694,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<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 @@ class ClassLinker {
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 @@ 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<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 @@ 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<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 @@ 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<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(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 d6e8dc0..10f64cc 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();