ART: Templatize dex-file-verifier check code
Templatize by item type to avoid repeated checks. This saves about
1.4% of instructions.
Bug: 78568168
Test: m test-art-host
Change-Id: I002c99ac1241a33ada85c1a991fb77ff06f76ebe
diff --git a/libdexfile/dex/dex_file_verifier.cc b/libdexfile/dex/dex_file_verifier.cc
index a91567f..73be166 100644
--- a/libdexfile/dex/dex_file_verifier.cc
+++ b/libdexfile/dex/dex_file_verifier.cc
@@ -1637,11 +1637,11 @@
return true;
}
-bool DexFileVerifier::CheckIntraSectionIterate(size_t offset, uint32_t section_count,
- DexFile::MapItemType type) {
+template <DexFile::MapItemType kType>
+bool DexFileVerifier::CheckIntraSectionIterate(size_t offset, uint32_t section_count) {
// Get the right alignment mask for the type of section.
size_t alignment_mask;
- switch (type) {
+ switch (kType) {
case DexFile::kDexTypeClassDataItem:
case DexFile::kDexTypeStringDataItem:
case DexFile::kDexTypeDebugInfoItem:
@@ -1659,13 +1659,13 @@
size_t aligned_offset = (offset + alignment_mask) & ~alignment_mask;
// Check the padding between items.
- if (!CheckPadding(offset, aligned_offset, type)) {
+ if (!CheckPadding(offset, aligned_offset, kType)) {
return false;
}
// Check depending on the section type.
const uint8_t* start_ptr = ptr_;
- switch (type) {
+ switch (kType) {
case DexFile::kDexTypeStringIdItem: {
if (!CheckListSize(ptr_, 1, sizeof(DexFile::StringId), "string_ids")) {
return false;
@@ -1788,17 +1788,17 @@
}
if (start_ptr == ptr_) {
- ErrorStringPrintf("Unknown map item type %x", type);
+ ErrorStringPrintf("Unknown map item type %x", kType);
return false;
}
- if (IsDataSectionType(type)) {
+ if (IsDataSectionType(kType)) {
if (aligned_offset == 0u) {
ErrorStringPrintf("Item %d offset is 0", i);
return false;
}
DCHECK(offset_to_type_map_.Find(aligned_offset) == offset_to_type_map_.end());
- offset_to_type_map_.Insert(std::pair<uint32_t, uint16_t>(aligned_offset, type));
+ offset_to_type_map_.Insert(std::pair<uint32_t, uint16_t>(aligned_offset, kType));
}
aligned_offset = ptr_ - begin_;
@@ -1813,6 +1813,55 @@
return true;
}
+bool DexFileVerifier::CheckIntraSectionIterateByType(size_t offset,
+ uint32_t count,
+ DexFile::MapItemType type) {
+ switch (type) {
+ case DexFile::kDexTypeHeaderItem:
+ return CheckIntraSectionIterate<DexFile::kDexTypeHeaderItem>(offset, count);
+ case DexFile::kDexTypeStringIdItem:
+ return CheckIntraSectionIterate<DexFile::kDexTypeStringIdItem>(offset, count);
+ case DexFile::kDexTypeTypeIdItem:
+ return CheckIntraSectionIterate<DexFile::kDexTypeTypeIdItem>(offset, count);
+ case DexFile::kDexTypeProtoIdItem:
+ return CheckIntraSectionIterate<DexFile::kDexTypeProtoIdItem>(offset, count);
+ case DexFile::kDexTypeFieldIdItem:
+ return CheckIntraSectionIterate<DexFile::kDexTypeFieldIdItem>(offset, count);
+ case DexFile::kDexTypeMethodIdItem:
+ return CheckIntraSectionIterate<DexFile::kDexTypeMethodIdItem>(offset, count);
+ case DexFile::kDexTypeClassDefItem:
+ return CheckIntraSectionIterate<DexFile::kDexTypeClassDefItem>(offset, count);
+ case DexFile::kDexTypeCallSiteIdItem:
+ return CheckIntraSectionIterate<DexFile::kDexTypeCallSiteIdItem>(offset, count);
+ case DexFile::kDexTypeMethodHandleItem:
+ return CheckIntraSectionIterate<DexFile::kDexTypeMethodHandleItem>(offset, count);
+ case DexFile::kDexTypeMapList:
+ return CheckIntraSectionIterate<DexFile::kDexTypeMapList>(offset, count);
+ case DexFile::kDexTypeTypeList:
+ return CheckIntraSectionIterate<DexFile::kDexTypeTypeList>(offset, count);
+ case DexFile::kDexTypeAnnotationSetRefList:
+ return CheckIntraSectionIterate<DexFile::kDexTypeAnnotationSetRefList>(offset, count);
+ case DexFile::kDexTypeAnnotationSetItem:
+ return CheckIntraSectionIterate<DexFile::kDexTypeAnnotationSetItem>(offset, count);
+ case DexFile::kDexTypeClassDataItem:
+ return CheckIntraSectionIterate<DexFile::kDexTypeClassDataItem>(offset, count);
+ case DexFile::kDexTypeCodeItem:
+ return CheckIntraSectionIterate<DexFile::kDexTypeCodeItem>(offset, count);
+ case DexFile::kDexTypeStringDataItem:
+ return CheckIntraSectionIterate<DexFile::kDexTypeStringDataItem>(offset, count);
+ case DexFile::kDexTypeDebugInfoItem:
+ return CheckIntraSectionIterate<DexFile::kDexTypeDebugInfoItem>(offset, count);
+ case DexFile::kDexTypeAnnotationItem:
+ return CheckIntraSectionIterate<DexFile::kDexTypeAnnotationItem>(offset, count);
+ case DexFile::kDexTypeEncodedArrayItem:
+ return CheckIntraSectionIterate<DexFile::kDexTypeEncodedArrayItem>(offset, count);
+ case DexFile::kDexTypeAnnotationsDirectoryItem:
+ return CheckIntraSectionIterate<DexFile::kDexTypeAnnotationsDirectoryItem>(offset, count);
+ }
+ LOG(FATAL) << "Unreachable";
+ UNREACHABLE();
+}
+
bool DexFileVerifier::CheckIntraIdSection(size_t offset,
uint32_t count,
DexFile::MapItemType type) {
@@ -1860,12 +1909,11 @@
return false;
}
- return CheckIntraSectionIterate(offset, count, type);
+ return CheckIntraSectionIterateByType(offset, count, type);
}
-bool DexFileVerifier::CheckIntraDataSection(size_t offset,
- uint32_t count,
- DexFile::MapItemType type) {
+template <DexFile::MapItemType kType>
+bool DexFileVerifier::CheckIntraDataSection(size_t offset, uint32_t count) {
size_t data_start = header_->data_off_;
size_t data_end = data_start + header_->data_size_;
@@ -1875,7 +1923,7 @@
return false;
}
- if (!CheckIntraSectionIterate(offset, count, type)) {
+ if (!CheckIntraSectionIterate<kType>(offset, count)) {
return false;
}
@@ -1952,21 +2000,75 @@
offset = section_offset + sizeof(uint32_t) + (map->size_ * sizeof(DexFile::MapItem));
break;
case DexFile::kDexTypeMethodHandleItem:
+ CheckIntraSectionIterate<DexFile::kDexTypeMethodHandleItem>(section_offset, section_count);
+ offset = ptr_ - begin_;
+ break;
case DexFile::kDexTypeCallSiteIdItem:
- CheckIntraSectionIterate(section_offset, section_count, type);
+ CheckIntraSectionIterate<DexFile::kDexTypeCallSiteIdItem>(section_offset, section_count);
offset = ptr_ - begin_;
break;
case DexFile::kDexTypeTypeList:
+ if (!CheckIntraDataSection<DexFile::kDexTypeTypeList>(section_offset, section_count)) {
+ return false;
+ }
+ offset = ptr_ - begin_;
+ break;
case DexFile::kDexTypeAnnotationSetRefList:
+ if (!CheckIntraDataSection<DexFile::kDexTypeAnnotationSetRefList>(section_offset,
+ section_count)) {
+ return false;
+ }
+ offset = ptr_ - begin_;
+ break;
case DexFile::kDexTypeAnnotationSetItem:
+ if (!CheckIntraDataSection<DexFile::kDexTypeAnnotationSetItem>(section_offset,
+ section_count)) {
+ return false;
+ }
+ offset = ptr_ - begin_;
+ break;
case DexFile::kDexTypeClassDataItem:
+ if (!CheckIntraDataSection<DexFile::kDexTypeClassDataItem>(section_offset, section_count)) {
+ return false;
+ }
+ offset = ptr_ - begin_;
+ break;
case DexFile::kDexTypeCodeItem:
+ if (!CheckIntraDataSection<DexFile::kDexTypeCodeItem>(section_offset, section_count)) {
+ return false;
+ }
+ offset = ptr_ - begin_;
+ break;
case DexFile::kDexTypeStringDataItem:
+ if (!CheckIntraDataSection<DexFile::kDexTypeStringDataItem>(section_offset,
+ section_count)) {
+ return false;
+ }
+ offset = ptr_ - begin_;
+ break;
case DexFile::kDexTypeDebugInfoItem:
+ if (!CheckIntraDataSection<DexFile::kDexTypeDebugInfoItem>(section_offset, section_count)) {
+ return false;
+ }
+ offset = ptr_ - begin_;
+ break;
case DexFile::kDexTypeAnnotationItem:
+ if (!CheckIntraDataSection<DexFile::kDexTypeAnnotationItem>(section_offset,
+ section_count)) {
+ return false;
+ }
+ offset = ptr_ - begin_;
+ break;
case DexFile::kDexTypeEncodedArrayItem:
+ if (!CheckIntraDataSection<DexFile::kDexTypeEncodedArrayItem>(section_offset,
+ section_count)) {
+ return false;
+ }
+ offset = ptr_ - begin_;
+ break;
case DexFile::kDexTypeAnnotationsDirectoryItem:
- if (!CheckIntraDataSection(section_offset, section_count, type)) {
+ if (!CheckIntraDataSection<DexFile::kDexTypeAnnotationsDirectoryItem>(section_offset,
+ section_count)) {
return false;
}
offset = ptr_ - begin_;
diff --git a/libdexfile/dex/dex_file_verifier.h b/libdexfile/dex/dex_file_verifier.h
index 4b73363..a4c23bb 100644
--- a/libdexfile/dex/dex_file_verifier.h
+++ b/libdexfile/dex/dex_file_verifier.h
@@ -119,9 +119,12 @@
bool CheckIntraAnnotationItem();
bool CheckIntraAnnotationsDirectoryItem();
- bool CheckIntraSectionIterate(size_t offset, uint32_t count, DexFile::MapItemType type);
+ template <DexFile::MapItemType kType>
+ bool CheckIntraSectionIterate(size_t offset, uint32_t count);
+ bool CheckIntraSectionIterateByType(size_t offset, uint32_t count, DexFile::MapItemType type);
bool CheckIntraIdSection(size_t offset, uint32_t count, DexFile::MapItemType type);
- bool CheckIntraDataSection(size_t offset, uint32_t count, DexFile::MapItemType type);
+ template <DexFile::MapItemType kType>
+ bool CheckIntraDataSection(size_t offset, uint32_t count);
bool CheckIntraSection();
bool CheckOffsetToTypeMap(size_t offset, uint16_t type);