summaryrefslogtreecommitdiff
path: root/dexlayout/dex_ir.h
diff options
context:
space:
mode:
Diffstat (limited to 'dexlayout/dex_ir.h')
-rw-r--r--dexlayout/dex_ir.h583
1 files changed, 232 insertions, 351 deletions
diff --git a/dexlayout/dex_ir.h b/dexlayout/dex_ir.h
index 54ff105820..9f355ba9e8 100644
--- a/dexlayout/dex_ir.h
+++ b/dexlayout/dex_ir.h
@@ -24,6 +24,7 @@
#include <map>
#include <vector>
+#include "base/iteration_range.h"
#include "base/leb128.h"
#include "base/stl_util.h"
#include "dex/dex_file-inl.h"
@@ -107,37 +108,153 @@ class AbstractDispatcher {
DISALLOW_COPY_AND_ASSIGN(AbstractDispatcher);
};
-// Collections become owners of the objects added by moving them into unique pointers.
-template<class T> class CollectionBase {
+template<class T> class Iterator : public std::iterator<std::random_access_iterator_tag, T> {
public:
- CollectionBase() = default;
+ using value_type = typename std::iterator<std::random_access_iterator_tag, T>::value_type;
+ using difference_type =
+ typename std::iterator<std::random_access_iterator_tag, value_type>::difference_type;
+ using pointer = typename std::iterator<std::random_access_iterator_tag, value_type>::pointer;
+ using reference = typename std::iterator<std::random_access_iterator_tag, value_type>::reference;
+
+ Iterator(const Iterator&) = default;
+ Iterator(Iterator&&) = default;
+ Iterator& operator=(const Iterator&) = default;
+ Iterator& operator=(Iterator&&) = default;
+
+ Iterator(const std::vector<T>& vector,
+ uint32_t position,
+ uint32_t iterator_end)
+ : vector_(&vector),
+ position_(position),
+ iterator_end_(iterator_end) { }
+ Iterator() : vector_(nullptr), position_(0U), iterator_end_(0U) { }
+
+ bool IsValid() const { return position_ < iterator_end_; }
+
+ bool operator==(const Iterator& rhs) const { return position_ == rhs.position_; }
+ bool operator!=(const Iterator& rhs) const { return !(*this == rhs); }
+ bool operator<(const Iterator& rhs) const { return position_ < rhs.position_; }
+ bool operator>(const Iterator& rhs) const { return rhs < *this; }
+ bool operator<=(const Iterator& rhs) const { return !(rhs < *this); }
+ bool operator>=(const Iterator& rhs) const { return !(*this < rhs); }
+
+ Iterator& operator++() { // Value after modification.
+ ++position_;
+ return *this;
+ }
- uint32_t GetOffset() const {
- return offset_;
+ Iterator operator++(int) {
+ Iterator temp = *this;
+ ++position_;
+ return temp;
+ }
+
+ Iterator& operator+=(difference_type delta) {
+ position_ += delta;
+ return *this;
+ }
+
+ Iterator operator+(difference_type delta) const {
+ Iterator temp = *this;
+ temp += delta;
+ return temp;
+ }
+
+ Iterator& operator--() { // Value after modification.
+ --position_;
+ return *this;
+ }
+
+ Iterator operator--(int) {
+ Iterator temp = *this;
+ --position_;
+ return temp;
}
- void SetOffset(uint32_t new_offset) {
- offset_ = new_offset;
+
+ Iterator& operator-=(difference_type delta) {
+ position_ -= delta;
+ return *this;
+ }
+
+ Iterator operator-(difference_type delta) const {
+ Iterator temp = *this;
+ temp -= delta;
+ return temp;
+ }
+
+ difference_type operator-(const Iterator& rhs) {
+ return position_ - rhs.position_;
+ }
+
+ reference operator*() const {
+ return const_cast<reference>((*vector_)[position_]);
+ }
+
+ pointer operator->() const {
+ return const_cast<pointer>(&((*vector_)[position_]));
+ }
+
+ reference operator[](difference_type n) const {
+ return (*vector_)[position_ + n];
}
private:
+ const std::vector<T>* vector_;
+ uint32_t position_;
+ uint32_t iterator_end_;
+
+ template <typename U>
+ friend bool operator<(const Iterator<U>& lhs, const Iterator<U>& rhs);
+};
+
+// Collections become owners of the objects added by moving them into unique pointers.
+class CollectionBase {
+ public:
+ CollectionBase() = default;
+ virtual ~CollectionBase() { }
+
+ uint32_t GetOffset() const { return offset_; }
+ void SetOffset(uint32_t new_offset) { offset_ = new_offset; }
+ virtual uint32_t Size() const { return 0U; }
+
+ private:
// Start out unassigned.
uint32_t offset_ = 0u;
DISALLOW_COPY_AND_ASSIGN(CollectionBase);
};
-template<class T> class CollectionVector : public CollectionBase<T> {
+template<class T> class CollectionVector : public CollectionBase {
public:
- using Vector = std::vector<std::unique_ptr<T>>;
+ using ElementType = std::unique_ptr<T>;
+
CollectionVector() { }
explicit CollectionVector(size_t size) {
// Preallocate so that assignment does not invalidate pointers into the vector.
collection_.reserve(size);
}
+ virtual ~CollectionVector() OVERRIDE { }
- uint32_t Size() const { return collection_.size(); }
- Vector& Collection() { return collection_; }
- const Vector& Collection() const { return collection_; }
+ template<class... Args>
+ T* CreateAndAddItem(Args&&... args) {
+ T* object = new T(std::forward<Args>(args)...);
+ collection_.push_back(std::unique_ptr<T>(object));
+ return object;
+ }
+
+ virtual uint32_t Size() const OVERRIDE { return collection_.size(); }
+
+ Iterator<ElementType> begin() const { return Iterator<ElementType>(collection_, 0U, Size()); }
+ Iterator<ElementType> end() const { return Iterator<ElementType>(collection_, Size(), Size()); }
+
+ const ElementType& operator[](size_t index) const {
+ DCHECK_LT(index, Size());
+ return collection_[index];
+ }
+ ElementType& operator[](size_t index) {
+ DCHECK_LT(index, Size());
+ return collection_[index];
+ }
// Sort the vector by copying pointers over.
template <typename MapType>
@@ -147,24 +264,16 @@ template<class T> class CollectionVector : public CollectionBase<T> {
for (size_t i = 0; i < Size(); ++i) {
// There are times when the array will temporarily contain the same pointer twice, doing the
// release here sure there is no double free errors.
- Collection()[i].release();
- Collection()[i].reset(it->second);
+ collection_[i].release();
+ collection_[i].reset(it->second);
++it;
}
}
protected:
- Vector collection_;
-
- template<class... Args>
- T* CreateAndAddItem(Args&&... args) {
- T* object = new T(std::forward<Args>(args)...);
- collection_.push_back(std::unique_ptr<T>(object));
- return object;
- }
+ std::vector<ElementType> collection_;
private:
- friend class Collections;
DISALLOW_COPY_AND_ASSIGN(CollectionVector);
};
@@ -174,7 +283,6 @@ template<class T> class IndexedCollectionVector : public CollectionVector<T> {
IndexedCollectionVector() = default;
explicit IndexedCollectionVector(size_t size) : CollectionVector<T>(size) { }
- private:
template <class... Args>
T* CreateAndAddIndexedItem(uint32_t index, Args&&... args) {
T* object = CollectionVector<T>::CreateAndAddItem(std::forward<Args>(args)...);
@@ -182,330 +290,13 @@ template<class T> class IndexedCollectionVector : public CollectionVector<T> {
return object;
}
- T* GetElement(uint32_t index) {
- DCHECK_LT(index, CollectionVector<T>::Size());
+ T* operator[](size_t index) const {
DCHECK_NE(CollectionVector<T>::collection_[index].get(), static_cast<T*>(nullptr));
return CollectionVector<T>::collection_[index].get();
}
- friend class Collections;
- DISALLOW_COPY_AND_ASSIGN(IndexedCollectionVector);
-};
-
-template<class T> class CollectionMap : public CollectionBase<T> {
- public:
- CollectionMap() = default;
-
- // Returns the existing item if it is already inserted, null otherwise.
- T* GetExistingObject(uint32_t offset) {
- auto it = collection_.find(offset);
- return it != collection_.end() ? it->second : nullptr;
- }
-
- // Lower case for template interop with std::map.
- uint32_t size() const { return collection_.size(); }
- std::map<uint32_t, T*>& Collection() { return collection_; }
-
private:
- std::map<uint32_t, T*> collection_;
-
- // CollectionMaps do not own the objects they contain, therefore AddItem is supported
- // rather than CreateAndAddItem.
- void AddItem(T* object, uint32_t offset) {
- auto it = collection_.emplace(offset, object);
- CHECK(it.second) << "CollectionMap already has an object with offset " << offset << " "
- << " and address " << it.first->second;
- }
-
- friend class Collections;
- DISALLOW_COPY_AND_ASSIGN(CollectionMap);
-};
-
-class Collections {
- public:
- Collections() = default;
- Collections(uint32_t num_string_ids,
- uint32_t num_type_ids,
- uint32_t num_proto_ids,
- uint32_t num_field_ids,
- uint32_t num_method_ids,
- uint32_t num_class_defs)
- : string_ids_(num_string_ids),
- type_ids_(num_type_ids),
- proto_ids_(num_proto_ids),
- field_ids_(num_field_ids),
- method_ids_(num_method_ids),
- class_defs_(num_class_defs) { }
-
- IndexedCollectionVector<StringId>::Vector& StringIds() { return string_ids_.Collection(); }
- IndexedCollectionVector<TypeId>::Vector& TypeIds() { return type_ids_.Collection(); }
- IndexedCollectionVector<ProtoId>::Vector& ProtoIds() { return proto_ids_.Collection(); }
- IndexedCollectionVector<FieldId>::Vector& FieldIds() { return field_ids_.Collection(); }
- IndexedCollectionVector<MethodId>::Vector& MethodIds() { return method_ids_.Collection(); }
- IndexedCollectionVector<ClassDef>::Vector& ClassDefs() { return class_defs_.Collection(); }
- CollectionVector<CallSiteId>::Vector& CallSiteIds() { return call_site_ids_.Collection(); }
- CollectionVector<MethodHandleItem>::Vector& MethodHandleItems()
- { return method_handle_items_.Collection(); }
- CollectionVector<StringData>::Vector& StringDatas() { return string_datas_.Collection(); }
- CollectionVector<TypeList>::Vector& TypeLists() { return type_lists_.Collection(); }
- CollectionVector<EncodedArrayItem>::Vector& EncodedArrayItems()
- { return encoded_array_items_.Collection(); }
- CollectionVector<AnnotationItem>::Vector& AnnotationItems()
- { return annotation_items_.Collection(); }
- CollectionVector<AnnotationSetItem>::Vector& AnnotationSetItems()
- { return annotation_set_items_.Collection(); }
- CollectionVector<AnnotationSetRefList>::Vector& AnnotationSetRefLists()
- { return annotation_set_ref_lists_.Collection(); }
- CollectionVector<AnnotationsDirectoryItem>::Vector& AnnotationsDirectoryItems()
- { return annotations_directory_items_.Collection(); }
- CollectionVector<DebugInfoItem>::Vector& DebugInfoItems()
- { return debug_info_items_.Collection(); }
- CollectionVector<CodeItem>::Vector& CodeItems() { return code_items_.Collection(); }
- CollectionVector<ClassData>::Vector& ClassDatas() { return class_datas_.Collection(); }
-
- const CollectionVector<ClassDef>::Vector& ClassDefs() const { return class_defs_.Collection(); }
-
- void CreateStringId(const DexFile& dex_file, uint32_t i);
- void CreateTypeId(const DexFile& dex_file, uint32_t i);
- void CreateProtoId(const DexFile& dex_file, uint32_t i);
- void CreateFieldId(const DexFile& dex_file, uint32_t i);
- void CreateMethodId(const DexFile& dex_file, uint32_t i);
- void CreateClassDef(const DexFile& dex_file, uint32_t i);
- void CreateCallSiteId(const DexFile& dex_file, uint32_t i);
- void CreateMethodHandleItem(const DexFile& dex_file, uint32_t i);
-
- void CreateCallSitesAndMethodHandles(const DexFile& dex_file);
-
- TypeList* CreateTypeList(const DexFile::TypeList* type_list, uint32_t offset);
- EncodedArrayItem* CreateEncodedArrayItem(const DexFile& dex_file,
- const uint8_t* static_data,
- uint32_t offset);
- AnnotationItem* CreateAnnotationItem(const DexFile& dex_file,
- const DexFile::AnnotationItem* annotation);
- AnnotationSetItem* CreateAnnotationSetItem(const DexFile& dex_file,
- const DexFile::AnnotationSetItem* disk_annotations_item, uint32_t offset);
- AnnotationsDirectoryItem* CreateAnnotationsDirectoryItem(const DexFile& dex_file,
- const DexFile::AnnotationsDirectoryItem* disk_annotations_item, uint32_t offset);
- CodeItem* DedupeOrCreateCodeItem(const DexFile& dex_file,
- const DexFile::CodeItem* disk_code_item,
- uint32_t offset,
- uint32_t dex_method_index);
- ClassData* CreateClassData(const DexFile& dex_file, const uint8_t* encoded_data, uint32_t offset);
- void AddAnnotationsFromMapListSection(const DexFile& dex_file,
- uint32_t start_offset,
- uint32_t count);
-
- StringId* GetStringId(uint32_t index) {
- return string_ids_.GetElement(index);
- }
- TypeId* GetTypeId(uint32_t index) {
- return type_ids_.GetElement(index);
- }
- ProtoId* GetProtoId(uint32_t index) {
- return proto_ids_.GetElement(index);
- }
- FieldId* GetFieldId(uint32_t index) {
- return field_ids_.GetElement(index);
- }
- MethodId* GetMethodId(uint32_t index) {
- return method_ids_.GetElement(index);
- }
- ClassDef* GetClassDef(uint32_t index) {
- return class_defs_.GetElement(index);
- }
- CallSiteId* GetCallSiteId(uint32_t index) {
- CHECK_LT(index, CallSiteIdsSize());
- return CallSiteIds()[index].get();
- }
- MethodHandleItem* GetMethodHandle(uint32_t index) {
- CHECK_LT(index, MethodHandleItemsSize());
- return MethodHandleItems()[index].get();
- }
-
- StringId* GetStringIdOrNullPtr(uint32_t index) {
- return index == dex::kDexNoIndex ? nullptr : GetStringId(index);
- }
- TypeId* GetTypeIdOrNullPtr(uint16_t index) {
- return index == DexFile::kDexNoIndex16 ? nullptr : GetTypeId(index);
- }
-
- uint32_t StringIdsOffset() const { return string_ids_.GetOffset(); }
- uint32_t TypeIdsOffset() const { return type_ids_.GetOffset(); }
- uint32_t ProtoIdsOffset() const { return proto_ids_.GetOffset(); }
- uint32_t FieldIdsOffset() const { return field_ids_.GetOffset(); }
- uint32_t MethodIdsOffset() const { return method_ids_.GetOffset(); }
- uint32_t ClassDefsOffset() const { return class_defs_.GetOffset(); }
- uint32_t CallSiteIdsOffset() const { return call_site_ids_.GetOffset(); }
- uint32_t MethodHandleItemsOffset() const { return method_handle_items_.GetOffset(); }
- uint32_t StringDatasOffset() const { return string_datas_.GetOffset(); }
- uint32_t TypeListsOffset() const { return type_lists_.GetOffset(); }
- uint32_t EncodedArrayItemsOffset() const { return encoded_array_items_.GetOffset(); }
- uint32_t AnnotationItemsOffset() const { return annotation_items_.GetOffset(); }
- uint32_t AnnotationSetItemsOffset() const { return annotation_set_items_.GetOffset(); }
- uint32_t AnnotationSetRefListsOffset() const { return annotation_set_ref_lists_.GetOffset(); }
- uint32_t AnnotationsDirectoryItemsOffset() const
- { return annotations_directory_items_.GetOffset(); }
- uint32_t DebugInfoItemsOffset() const { return debug_info_items_.GetOffset(); }
- uint32_t CodeItemsOffset() const { return code_items_.GetOffset(); }
- uint32_t ClassDatasOffset() const { return class_datas_.GetOffset(); }
- uint32_t MapListOffset() const { return map_list_offset_; }
-
- void SetStringIdsOffset(uint32_t new_offset) { string_ids_.SetOffset(new_offset); }
- void SetTypeIdsOffset(uint32_t new_offset) { type_ids_.SetOffset(new_offset); }
- void SetProtoIdsOffset(uint32_t new_offset) { proto_ids_.SetOffset(new_offset); }
- void SetFieldIdsOffset(uint32_t new_offset) { field_ids_.SetOffset(new_offset); }
- void SetMethodIdsOffset(uint32_t new_offset) { method_ids_.SetOffset(new_offset); }
- void SetClassDefsOffset(uint32_t new_offset) { class_defs_.SetOffset(new_offset); }
- void SetCallSiteIdsOffset(uint32_t new_offset) { call_site_ids_.SetOffset(new_offset); }
- void SetMethodHandleItemsOffset(uint32_t new_offset)
- { method_handle_items_.SetOffset(new_offset); }
- void SetStringDatasOffset(uint32_t new_offset) { string_datas_.SetOffset(new_offset); }
- void SetTypeListsOffset(uint32_t new_offset) { type_lists_.SetOffset(new_offset); }
- void SetEncodedArrayItemsOffset(uint32_t new_offset)
- { encoded_array_items_.SetOffset(new_offset); }
- void SetAnnotationItemsOffset(uint32_t new_offset) { annotation_items_.SetOffset(new_offset); }
- void SetAnnotationSetItemsOffset(uint32_t new_offset)
- { annotation_set_items_.SetOffset(new_offset); }
- void SetAnnotationSetRefListsOffset(uint32_t new_offset)
- { annotation_set_ref_lists_.SetOffset(new_offset); }
- void SetAnnotationsDirectoryItemsOffset(uint32_t new_offset)
- { annotations_directory_items_.SetOffset(new_offset); }
- void SetDebugInfoItemsOffset(uint32_t new_offset) { debug_info_items_.SetOffset(new_offset); }
- void SetCodeItemsOffset(uint32_t new_offset) { code_items_.SetOffset(new_offset); }
- void SetClassDatasOffset(uint32_t new_offset) { class_datas_.SetOffset(new_offset); }
- void SetMapListOffset(uint32_t new_offset) { map_list_offset_ = new_offset; }
-
- uint32_t StringIdsSize() const { return string_ids_.Size(); }
- uint32_t TypeIdsSize() const { return type_ids_.Size(); }
- uint32_t ProtoIdsSize() const { return proto_ids_.Size(); }
- uint32_t FieldIdsSize() const { return field_ids_.Size(); }
- uint32_t MethodIdsSize() const { return method_ids_.Size(); }
- uint32_t ClassDefsSize() const { return class_defs_.Size(); }
- uint32_t CallSiteIdsSize() const { return call_site_ids_.Size(); }
- uint32_t MethodHandleItemsSize() const { return method_handle_items_.Size(); }
- uint32_t StringDatasSize() const { return string_datas_.Size(); }
- uint32_t TypeListsSize() const { return type_lists_.Size(); }
- uint32_t EncodedArrayItemsSize() const { return encoded_array_items_.Size(); }
- uint32_t AnnotationItemsSize() const { return annotation_items_.Size(); }
- uint32_t AnnotationSetItemsSize() const { return annotation_set_items_.Size(); }
- uint32_t AnnotationSetRefListsSize() const { return annotation_set_ref_lists_.Size(); }
- uint32_t AnnotationsDirectoryItemsSize() const { return annotations_directory_items_.Size(); }
- uint32_t DebugInfoItemsSize() const { return debug_info_items_.Size(); }
- uint32_t CodeItemsSize() const { return code_items_.Size(); }
- uint32_t ClassDatasSize() const { return class_datas_.Size(); }
-
- // Sort the vectors buy map order (same order that was used in the input file).
- void SortVectorsByMapOrder();
- // Empty the maps, which are only used for IR construction.
- void ClearMaps();
-
- template <typename Type, class... Args>
- Type* CreateAndAddItem(CollectionMap<Type>& map,
- CollectionVector<Type>& vector,
- uint32_t offset,
- Args&&... args) {
- Type* item = vector.CreateAndAddItem(std::forward<Args>(args)...);
- DCHECK(!map.GetExistingObject(offset));
- DCHECK(!item->OffsetAssigned());
- if (eagerly_assign_offsets_) {
- item->SetOffset(offset);
- }
- map.AddItem(item, offset);
- return item;
- }
-
- template <typename Type, class... Args>
- Type* CreateAndAddIndexedItem(IndexedCollectionVector<Type>& vector,
- uint32_t offset,
- uint32_t index,
- Args&&... args) {
- Type* item = vector.CreateAndAddIndexedItem(index, std::forward<Args>(args)...);
- DCHECK(!item->OffsetAssigned());
- if (eagerly_assign_offsets_) {
- item->SetOffset(offset);
- }
- return item;
- }
-
- void SetEagerlyAssignOffsets(bool eagerly_assign_offsets) {
- eagerly_assign_offsets_ = eagerly_assign_offsets;
- }
-
- void SetLinkData(std::vector<uint8_t>&& link_data) {
- link_data_ = std::move(link_data);
- }
-
- const std::vector<uint8_t>& LinkData() const {
- return link_data_;
- }
-
- private:
- EncodedValue* ReadEncodedValue(const DexFile& dex_file, const uint8_t** data);
- EncodedValue* ReadEncodedValue(const DexFile& dex_file,
- const uint8_t** data,
- uint8_t type,
- uint8_t length);
- void ReadEncodedValue(const DexFile& dex_file,
- const uint8_t** data,
- uint8_t type,
- uint8_t length,
- EncodedValue* item);
-
- ParameterAnnotation* GenerateParameterAnnotation(const DexFile& dex_file, MethodId* method_id,
- const DexFile::AnnotationSetRefList* annotation_set_ref_list, uint32_t offset);
- MethodItem GenerateMethodItem(const DexFile& dex_file, ClassDataItemIterator& cdii);
-
- // Collection vectors own the IR data.
- IndexedCollectionVector<StringId> string_ids_;
- IndexedCollectionVector<TypeId> type_ids_;
- IndexedCollectionVector<ProtoId> proto_ids_;
- IndexedCollectionVector<FieldId> field_ids_;
- IndexedCollectionVector<MethodId> method_ids_;
- IndexedCollectionVector<ClassDef> class_defs_;
- IndexedCollectionVector<CallSiteId> call_site_ids_;
- IndexedCollectionVector<MethodHandleItem> method_handle_items_;
- IndexedCollectionVector<StringData> string_datas_;
- IndexedCollectionVector<TypeList> type_lists_;
- IndexedCollectionVector<EncodedArrayItem> encoded_array_items_;
- IndexedCollectionVector<AnnotationItem> annotation_items_;
- IndexedCollectionVector<AnnotationSetItem> annotation_set_items_;
- IndexedCollectionVector<AnnotationSetRefList> annotation_set_ref_lists_;
- IndexedCollectionVector<AnnotationsDirectoryItem> annotations_directory_items_;
- // The order of the vectors controls the layout of the output file by index order, to change the
- // layout just sort the vector. Note that you may only change the order of the non indexed vectors
- // below. Indexed vectors are accessed by indices in other places, changing the sorting order will
- // invalidate the existing indices and is not currently supported.
- CollectionVector<DebugInfoItem> debug_info_items_;
- CollectionVector<CodeItem> code_items_;
- CollectionVector<ClassData> class_datas_;
-
- // Note that the maps do not have ownership, the vectors do.
- // TODO: These maps should only be required for building the IR and should be put in a separate
- // IR builder class.
- CollectionMap<StringData> string_datas_map_;
- CollectionMap<TypeList> type_lists_map_;
- CollectionMap<EncodedArrayItem> encoded_array_items_map_;
- CollectionMap<AnnotationItem> annotation_items_map_;
- CollectionMap<AnnotationSetItem> annotation_set_items_map_;
- CollectionMap<AnnotationSetRefList> annotation_set_ref_lists_map_;
- CollectionMap<AnnotationsDirectoryItem> annotations_directory_items_map_;
- CollectionMap<DebugInfoItem> debug_info_items_map_;
- // Code item maps need to check both the debug info offset and debug info offset, do not use
- // CollectionMap.
- // First offset is the code item offset, second is the debug info offset.
- std::map<std::pair<uint32_t, uint32_t>, CodeItem*> code_items_map_;
- CollectionMap<ClassData> class_datas_map_;
-
- uint32_t map_list_offset_ = 0;
-
- // Link data.
- std::vector<uint8_t> link_data_;
-
- // If we eagerly assign offsets during IR building or later after layout. Must be false if
- // changing the layout is enabled.
- bool eagerly_assign_offsets_;
-
- DISALLOW_COPY_AND_ASSIGN(Collections);
+ DISALLOW_COPY_AND_ASSIGN(IndexedCollectionVector);
};
class Item {
@@ -598,12 +389,12 @@ class Header : public Item {
uint32_t num_class_defs)
: Item(0, kHeaderItemSize),
support_default_methods_(support_default_methods),
- collections_(num_string_ids,
- num_type_ids,
- num_proto_ids,
- num_field_ids,
- num_method_ids,
- num_class_defs) {
+ string_ids_(num_string_ids),
+ type_ids_(num_type_ids),
+ proto_ids_(num_proto_ids),
+ field_ids_(num_field_ids),
+ method_ids_(num_method_ids),
+ class_defs_(num_class_defs) {
ConstructorHelper(magic,
checksum,
signature,
@@ -641,7 +432,69 @@ class Header : public Item {
void SetDataSize(uint32_t new_data_size) { data_size_ = new_data_size; }
void SetDataOffset(uint32_t new_data_offset) { data_offset_ = new_data_offset; }
- Collections& GetCollections() { return collections_; }
+ IndexedCollectionVector<StringId>& StringIds() { return string_ids_; }
+ const IndexedCollectionVector<StringId>& StringIds() const { return string_ids_; }
+ IndexedCollectionVector<TypeId>& TypeIds() { return type_ids_; }
+ const IndexedCollectionVector<TypeId>& TypeIds() const { return type_ids_; }
+ IndexedCollectionVector<ProtoId>& ProtoIds() { return proto_ids_; }
+ const IndexedCollectionVector<ProtoId>& ProtoIds() const { return proto_ids_; }
+ IndexedCollectionVector<FieldId>& FieldIds() { return field_ids_; }
+ const IndexedCollectionVector<FieldId>& FieldIds() const { return field_ids_; }
+ IndexedCollectionVector<MethodId>& MethodIds() { return method_ids_; }
+ const IndexedCollectionVector<MethodId>& MethodIds() const { return method_ids_; }
+ IndexedCollectionVector<ClassDef>& ClassDefs() { return class_defs_; }
+ const IndexedCollectionVector<ClassDef>& ClassDefs() const { return class_defs_; }
+ IndexedCollectionVector<CallSiteId>& CallSiteIds() { return call_site_ids_; }
+ const IndexedCollectionVector<CallSiteId>& CallSiteIds() const { return call_site_ids_; }
+ IndexedCollectionVector<MethodHandleItem>& MethodHandleItems() { return method_handle_items_; }
+ const IndexedCollectionVector<MethodHandleItem>& MethodHandleItems() const {
+ return method_handle_items_;
+ }
+ CollectionVector<StringData>& StringDatas() { return string_datas_; }
+ const CollectionVector<StringData>& StringDatas() const { return string_datas_; }
+ CollectionVector<TypeList>& TypeLists() { return type_lists_; }
+ const CollectionVector<TypeList>& TypeLists() const { return type_lists_; }
+ CollectionVector<EncodedArrayItem>& EncodedArrayItems() { return encoded_array_items_; }
+ const CollectionVector<EncodedArrayItem>& EncodedArrayItems() const {
+ return encoded_array_items_;
+ }
+ CollectionVector<AnnotationItem>& AnnotationItems() { return annotation_items_; }
+ const CollectionVector<AnnotationItem>& AnnotationItems() const { return annotation_items_; }
+ CollectionVector<AnnotationSetItem>& AnnotationSetItems() { return annotation_set_items_; }
+ const CollectionVector<AnnotationSetItem>& AnnotationSetItems() const {
+ return annotation_set_items_;
+ }
+ CollectionVector<AnnotationSetRefList>& AnnotationSetRefLists() {
+ return annotation_set_ref_lists_;
+ }
+ const CollectionVector<AnnotationSetRefList>& AnnotationSetRefLists() const {
+ return annotation_set_ref_lists_;
+ }
+ CollectionVector<AnnotationsDirectoryItem>& AnnotationsDirectoryItems() {
+ return annotations_directory_items_;
+ }
+ const CollectionVector<AnnotationsDirectoryItem>& AnnotationsDirectoryItems() const {
+ return annotations_directory_items_;
+ }
+ CollectionVector<DebugInfoItem>& DebugInfoItems() { return debug_info_items_; }
+ const CollectionVector<DebugInfoItem>& DebugInfoItems() const { return debug_info_items_; }
+ CollectionVector<CodeItem>& CodeItems() { return code_items_; }
+ const CollectionVector<CodeItem>& CodeItems() const { return code_items_; }
+ CollectionVector<ClassData>& ClassDatas() { return class_datas_; }
+ const CollectionVector<ClassData>& ClassDatas() const { return class_datas_; }
+
+ StringId* GetStringIdOrNullPtr(uint32_t index) {
+ return index == dex::kDexNoIndex ? nullptr : StringIds()[index];
+ }
+ TypeId* GetTypeIdOrNullPtr(uint16_t index) {
+ return index == DexFile::kDexNoIndex16 ? nullptr : TypeIds()[index];
+ }
+
+ uint32_t MapListOffset() const { return map_list_offset_; }
+ void SetMapListOffset(uint32_t new_offset) { map_list_offset_ = new_offset; }
+
+ const std::vector<uint8_t>& LinkData() const { return link_data_; }
+ void SetLinkData(std::vector<uint8_t>&& link_data) { link_data_ = std::move(link_data); }
void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
@@ -683,7 +536,35 @@ class Header : public Item {
memcpy(magic_, magic, sizeof(magic_));
memcpy(signature_, signature, sizeof(signature_));
}
- Collections collections_;
+
+ // Collection vectors own the IR data.
+ IndexedCollectionVector<StringId> string_ids_;
+ IndexedCollectionVector<TypeId> type_ids_;
+ IndexedCollectionVector<ProtoId> proto_ids_;
+ IndexedCollectionVector<FieldId> field_ids_;
+ IndexedCollectionVector<MethodId> method_ids_;
+ IndexedCollectionVector<ClassDef> class_defs_;
+ IndexedCollectionVector<CallSiteId> call_site_ids_;
+ IndexedCollectionVector<MethodHandleItem> method_handle_items_;
+ IndexedCollectionVector<StringData> string_datas_;
+ IndexedCollectionVector<TypeList> type_lists_;
+ IndexedCollectionVector<EncodedArrayItem> encoded_array_items_;
+ IndexedCollectionVector<AnnotationItem> annotation_items_;
+ IndexedCollectionVector<AnnotationSetItem> annotation_set_items_;
+ IndexedCollectionVector<AnnotationSetRefList> annotation_set_ref_lists_;
+ IndexedCollectionVector<AnnotationsDirectoryItem> annotations_directory_items_;
+ // The order of the vectors controls the layout of the output file by index order, to change the
+ // layout just sort the vector. Note that you may only change the order of the non indexed vectors
+ // below. Indexed vectors are accessed by indices in other places, changing the sorting order will
+ // invalidate the existing indices and is not currently supported.
+ CollectionVector<DebugInfoItem> debug_info_items_;
+ CollectionVector<CodeItem> code_items_;
+ CollectionVector<ClassData> class_datas_;
+
+ uint32_t map_list_offset_ = 0;
+
+ // Link data.
+ std::vector<uint8_t> link_data_;
DISALLOW_COPY_AND_ASSIGN(Header);
};