ART: Templatize DexFileVerifier::CheckIntraIdSection().
And use macros in DexFileVerifier::CheckIntraSection() to
avoid code duplication.
This is a follow-up to
https://android-review.googlesource.com/672438
but the improvements in instruction count measured on host
with "perf stat dexdump2 -c <large apk>" are absolutely
insignificant (0.0003%).
Test: Rely on TreeHugger.
Change-Id: I95fd3b2f7f2d767e5446dd71552b34ea55f4bd47
diff --git a/libdexfile/dex/dex_file_verifier.cc b/libdexfile/dex/dex_file_verifier.cc
index ba65fc9..a32f64e 100644
--- a/libdexfile/dex/dex_file_verifier.cc
+++ b/libdexfile/dex/dex_file_verifier.cc
@@ -1761,63 +1761,13 @@
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) {
+template <DexFile::MapItemType kType>
+bool DexFileVerifier::CheckIntraIdSection(size_t offset, uint32_t count) {
uint32_t expected_offset;
uint32_t expected_size;
// Get the expected offset and size from the header.
- switch (type) {
+ switch (kType) {
case DexFile::kDexTypeStringIdItem:
expected_offset = header_->string_ids_off_;
expected_size = header_->string_ids_size_;
@@ -1843,7 +1793,7 @@
expected_size = header_->class_defs_size_;
break;
default:
- ErrorStringPrintf("Bad type for id section: %x", type);
+ ErrorStringPrintf("Bad type for id section: %x", kType);
return false;
}
@@ -1857,7 +1807,7 @@
return false;
}
- return CheckIntraSectionIterateByType(offset, count, type);
+ return CheckIntraSectionIterate<kType>(offset, count);
}
template <DexFile::MapItemType kType>
@@ -1888,7 +1838,8 @@
}
bool DexFileVerifier::CheckIntraSection() {
- const DexFile::MapList* map = reinterpret_cast<const DexFile::MapList*>(begin_ + header_->map_off_);
+ const DexFile::MapList* map =
+ reinterpret_cast<const DexFile::MapList*>(begin_ + header_->map_off_);
const DexFile::MapItem* item = map->list_;
size_t offset = 0;
uint32_t count = map->size_;
@@ -1927,17 +1878,22 @@
ptr_ = begin_ + header_->header_size_;
offset = header_->header_size_;
break;
- case DexFile::kDexTypeStringIdItem:
- case DexFile::kDexTypeTypeIdItem:
- case DexFile::kDexTypeProtoIdItem:
- case DexFile::kDexTypeFieldIdItem:
- case DexFile::kDexTypeMethodIdItem:
- case DexFile::kDexTypeClassDefItem:
- if (!CheckIntraIdSection(section_offset, section_count, type)) {
- return false;
- }
- offset = ptr_ - begin_;
+
+#define CHECK_INTRA_ID_SECTION_CASE(type) \
+ case type: \
+ if (!CheckIntraIdSection<type>(section_offset, section_count)) { \
+ return false; \
+ } \
+ offset = ptr_ - begin_; \
break;
+ CHECK_INTRA_ID_SECTION_CASE(DexFile::kDexTypeStringIdItem)
+ CHECK_INTRA_ID_SECTION_CASE(DexFile::kDexTypeTypeIdItem)
+ CHECK_INTRA_ID_SECTION_CASE(DexFile::kDexTypeProtoIdItem)
+ CHECK_INTRA_ID_SECTION_CASE(DexFile::kDexTypeFieldIdItem)
+ CHECK_INTRA_ID_SECTION_CASE(DexFile::kDexTypeMethodIdItem)
+ CHECK_INTRA_ID_SECTION_CASE(DexFile::kDexTypeClassDefItem)
+#undef CHECK_INTRA_ID_SECTION_CASE
+
case DexFile::kDexTypeMapList:
if (UNLIKELY(section_count != 1)) {
ErrorStringPrintf("Multiple map list items");
@@ -1951,80 +1907,34 @@
ptr_ += sizeof(uint32_t) + (map->size_ * sizeof(DexFile::MapItem));
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_;
+
+#define CHECK_INTRA_SECTION_ITERATE_CASE(type) \
+ case type: \
+ CheckIntraSectionIterate<type>(section_offset, section_count); \
+ offset = ptr_ - begin_; \
break;
- case DexFile::kDexTypeCallSiteIdItem:
- CheckIntraSectionIterate<DexFile::kDexTypeCallSiteIdItem>(section_offset, section_count);
- offset = ptr_ - begin_;
+ CHECK_INTRA_SECTION_ITERATE_CASE(DexFile::kDexTypeMethodHandleItem)
+ CHECK_INTRA_SECTION_ITERATE_CASE(DexFile::kDexTypeCallSiteIdItem)
+#undef CHECK_INTRA_SECTION_ITERATE_CASE
+
+#define CHECK_INTRA_DATA_SECTION_CASE(type) \
+ case type: \
+ if (!CheckIntraDataSection<type>(section_offset, section_count)) { \
+ return false; \
+ } \
+ 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<DexFile::kDexTypeAnnotationsDirectoryItem>(section_offset,
- section_count)) {
- return false;
- }
- offset = ptr_ - begin_;
- break;
+ CHECK_INTRA_DATA_SECTION_CASE(DexFile::kDexTypeTypeList)
+ CHECK_INTRA_DATA_SECTION_CASE(DexFile::kDexTypeAnnotationSetRefList)
+ CHECK_INTRA_DATA_SECTION_CASE(DexFile::kDexTypeAnnotationSetItem)
+ CHECK_INTRA_DATA_SECTION_CASE(DexFile::kDexTypeClassDataItem)
+ CHECK_INTRA_DATA_SECTION_CASE(DexFile::kDexTypeCodeItem)
+ CHECK_INTRA_DATA_SECTION_CASE(DexFile::kDexTypeStringDataItem)
+ CHECK_INTRA_DATA_SECTION_CASE(DexFile::kDexTypeDebugInfoItem)
+ CHECK_INTRA_DATA_SECTION_CASE(DexFile::kDexTypeAnnotationItem)
+ CHECK_INTRA_DATA_SECTION_CASE(DexFile::kDexTypeEncodedArrayItem)
+ CHECK_INTRA_DATA_SECTION_CASE(DexFile::kDexTypeAnnotationsDirectoryItem)
+#undef CHECK_INTRA_DATA_SECTION_CASE
}
if (offset == current_offset) {
diff --git a/libdexfile/dex/dex_file_verifier.h b/libdexfile/dex/dex_file_verifier.h
index eaffc62..04d8d71 100644
--- a/libdexfile/dex/dex_file_verifier.h
+++ b/libdexfile/dex/dex_file_verifier.h
@@ -126,8 +126,8 @@
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);
+ template <DexFile::MapItemType kType>
+ bool CheckIntraIdSection(size_t offset, uint32_t count);
template <DexFile::MapItemType kType>
bool CheckIntraDataSection(size_t offset, uint32_t count);
bool CheckIntraSection();