Home | History | Annotate | Download | only in dexlayout
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  *
     16  * Header file of an in-memory representation of DEX files.
     17  */
     18 
     19 #ifndef ART_DEXLAYOUT_DEX_IR_H_
     20 #define ART_DEXLAYOUT_DEX_IR_H_
     21 
     22 #include <stdint.h>
     23 
     24 #include <map>
     25 #include <vector>
     26 
     27 #include "base/leb128.h"
     28 #include "base/stl_util.h"
     29 #include "dex/dex_file-inl.h"
     30 #include "dex/dex_file_types.h"
     31 #include "dex/utf.h"
     32 
     33 namespace art {
     34 namespace dex_ir {
     35 
     36 // Forward declarations for classes used in containers or pointed to.
     37 class AnnotationItem;
     38 class AnnotationsDirectoryItem;
     39 class AnnotationSetItem;
     40 class AnnotationSetRefList;
     41 class CallSiteId;
     42 class ClassData;
     43 class ClassDef;
     44 class CodeItem;
     45 class DebugInfoItem;
     46 class EncodedAnnotation;
     47 class EncodedArrayItem;
     48 class EncodedValue;
     49 class FieldId;
     50 class FieldItem;
     51 class Header;
     52 class MapList;
     53 class MapItem;
     54 class MethodHandleItem;
     55 class MethodId;
     56 class MethodItem;
     57 class ParameterAnnotation;
     58 class ProtoId;
     59 class StringData;
     60 class StringId;
     61 class TryItem;
     62 class TypeId;
     63 class TypeList;
     64 
     65 // Item size constants.
     66 static constexpr size_t kHeaderItemSize = 112;
     67 static constexpr size_t kStringIdItemSize = 4;
     68 static constexpr size_t kTypeIdItemSize = 4;
     69 static constexpr size_t kProtoIdItemSize = 12;
     70 static constexpr size_t kFieldIdItemSize = 8;
     71 static constexpr size_t kMethodIdItemSize = 8;
     72 static constexpr size_t kClassDefItemSize = 32;
     73 static constexpr size_t kCallSiteIdItemSize = 4;
     74 static constexpr size_t kMethodHandleItemSize = 8;
     75 
     76 // Visitor support
     77 class AbstractDispatcher {
     78  public:
     79   AbstractDispatcher() = default;
     80   virtual ~AbstractDispatcher() { }
     81 
     82   virtual void Dispatch(Header* header) = 0;
     83   virtual void Dispatch(const StringData* string_data) = 0;
     84   virtual void Dispatch(const StringId* string_id) = 0;
     85   virtual void Dispatch(const TypeId* type_id) = 0;
     86   virtual void Dispatch(const ProtoId* proto_id) = 0;
     87   virtual void Dispatch(const FieldId* field_id) = 0;
     88   virtual void Dispatch(const MethodId* method_id) = 0;
     89   virtual void Dispatch(const CallSiteId* call_site_id) = 0;
     90   virtual void Dispatch(const MethodHandleItem* method_handle_item) = 0;
     91   virtual void Dispatch(ClassData* class_data) = 0;
     92   virtual void Dispatch(ClassDef* class_def) = 0;
     93   virtual void Dispatch(FieldItem* field_item) = 0;
     94   virtual void Dispatch(MethodItem* method_item) = 0;
     95   virtual void Dispatch(EncodedArrayItem* array_item) = 0;
     96   virtual void Dispatch(CodeItem* code_item) = 0;
     97   virtual void Dispatch(TryItem* try_item) = 0;
     98   virtual void Dispatch(DebugInfoItem* debug_info_item) = 0;
     99   virtual void Dispatch(AnnotationItem* annotation_item) = 0;
    100   virtual void Dispatch(AnnotationSetItem* annotation_set_item) = 0;
    101   virtual void Dispatch(AnnotationSetRefList* annotation_set_ref_list) = 0;
    102   virtual void Dispatch(AnnotationsDirectoryItem* annotations_directory_item) = 0;
    103   virtual void Dispatch(MapList* map_list) = 0;
    104   virtual void Dispatch(MapItem* map_item) = 0;
    105 
    106  private:
    107   DISALLOW_COPY_AND_ASSIGN(AbstractDispatcher);
    108 };
    109 
    110 // Collections become owners of the objects added by moving them into unique pointers.
    111 template<class T> class CollectionBase {
    112  public:
    113   CollectionBase() = default;
    114 
    115   uint32_t GetOffset() const {
    116     return offset_;
    117   }
    118   void SetOffset(uint32_t new_offset) {
    119     offset_ = new_offset;
    120   }
    121 
    122  private:
    123   // Start out unassigned.
    124   uint32_t offset_ = 0u;
    125 
    126   DISALLOW_COPY_AND_ASSIGN(CollectionBase);
    127 };
    128 
    129 template<class T> class CollectionVector : public CollectionBase<T> {
    130  public:
    131   using Vector = std::vector<std::unique_ptr<T>>;
    132   CollectionVector() = default;
    133 
    134   uint32_t Size() const { return collection_.size(); }
    135   Vector& Collection() { return collection_; }
    136   const Vector& Collection() const { return collection_; }
    137 
    138   // Sort the vector by copying pointers over.
    139   template <typename MapType>
    140   void SortByMapOrder(const MapType& map) {
    141     auto it = map.begin();
    142     CHECK_EQ(map.size(), Size());
    143     for (size_t i = 0; i < Size(); ++i) {
    144       // There are times when the array will temporarily contain the same pointer twice, doing the
    145       // release here sure there is no double free errors.
    146       Collection()[i].release();
    147       Collection()[i].reset(it->second);
    148       ++it;
    149     }
    150   }
    151 
    152  protected:
    153   Vector collection_;
    154 
    155   void AddItem(T* object) {
    156     collection_.push_back(std::unique_ptr<T>(object));
    157   }
    158 
    159  private:
    160   friend class Collections;
    161   DISALLOW_COPY_AND_ASSIGN(CollectionVector);
    162 };
    163 
    164 template<class T> class IndexedCollectionVector : public CollectionVector<T> {
    165  public:
    166   using Vector = std::vector<std::unique_ptr<T>>;
    167   IndexedCollectionVector() = default;
    168 
    169  private:
    170   void AddIndexedItem(T* object, uint32_t index) {
    171     object->SetIndex(index);
    172     CollectionVector<T>::collection_.push_back(std::unique_ptr<T>(object));
    173   }
    174 
    175   friend class Collections;
    176   DISALLOW_COPY_AND_ASSIGN(IndexedCollectionVector);
    177 };
    178 
    179 template<class T> class CollectionMap : public CollectionBase<T> {
    180  public:
    181   CollectionMap() = default;
    182 
    183   // Returns the existing item if it is already inserted, null otherwise.
    184   T* GetExistingObject(uint32_t offset) {
    185     auto it = collection_.find(offset);
    186     return it != collection_.end() ? it->second : nullptr;
    187   }
    188 
    189   // Lower case for template interop with std::map.
    190   uint32_t size() const { return collection_.size(); }
    191   std::map<uint32_t, T*>& Collection() { return collection_; }
    192 
    193  private:
    194   std::map<uint32_t, T*> collection_;
    195 
    196   void AddItem(T* object, uint32_t offset) {
    197     auto it = collection_.emplace(offset, object);
    198     CHECK(it.second) << "CollectionMap already has an object with offset " << offset << " "
    199                      << " and address " << it.first->second;
    200   }
    201 
    202   friend class Collections;
    203   DISALLOW_COPY_AND_ASSIGN(CollectionMap);
    204 };
    205 
    206 class Collections {
    207  public:
    208   Collections() = default;
    209 
    210   CollectionVector<StringId>::Vector& StringIds() { return string_ids_.Collection(); }
    211   CollectionVector<TypeId>::Vector& TypeIds() { return type_ids_.Collection(); }
    212   CollectionVector<ProtoId>::Vector& ProtoIds() { return proto_ids_.Collection(); }
    213   CollectionVector<FieldId>::Vector& FieldIds() { return field_ids_.Collection(); }
    214   CollectionVector<MethodId>::Vector& MethodIds() { return method_ids_.Collection(); }
    215   CollectionVector<ClassDef>::Vector& ClassDefs() { return class_defs_.Collection(); }
    216   CollectionVector<CallSiteId>::Vector& CallSiteIds() { return call_site_ids_.Collection(); }
    217   CollectionVector<MethodHandleItem>::Vector& MethodHandleItems()
    218       { return method_handle_items_.Collection(); }
    219   CollectionVector<StringData>::Vector& StringDatas() { return string_datas_.Collection(); }
    220   CollectionVector<TypeList>::Vector& TypeLists() { return type_lists_.Collection(); }
    221   CollectionVector<EncodedArrayItem>::Vector& EncodedArrayItems()
    222       { return encoded_array_items_.Collection(); }
    223   CollectionVector<AnnotationItem>::Vector& AnnotationItems()
    224       { return annotation_items_.Collection(); }
    225   CollectionVector<AnnotationSetItem>::Vector& AnnotationSetItems()
    226       { return annotation_set_items_.Collection(); }
    227   CollectionVector<AnnotationSetRefList>::Vector& AnnotationSetRefLists()
    228       { return annotation_set_ref_lists_.Collection(); }
    229   CollectionVector<AnnotationsDirectoryItem>::Vector& AnnotationsDirectoryItems()
    230       { return annotations_directory_items_.Collection(); }
    231   CollectionVector<DebugInfoItem>::Vector& DebugInfoItems()
    232       { return debug_info_items_.Collection(); }
    233   CollectionVector<CodeItem>::Vector& CodeItems() { return code_items_.Collection(); }
    234   CollectionVector<ClassData>::Vector& ClassDatas() { return class_datas_.Collection(); }
    235 
    236   const CollectionVector<ClassDef>::Vector& ClassDefs() const { return class_defs_.Collection(); }
    237 
    238   void CreateStringId(const DexFile& dex_file, uint32_t i);
    239   void CreateTypeId(const DexFile& dex_file, uint32_t i);
    240   void CreateProtoId(const DexFile& dex_file, uint32_t i);
    241   void CreateFieldId(const DexFile& dex_file, uint32_t i);
    242   void CreateMethodId(const DexFile& dex_file, uint32_t i);
    243   void CreateClassDef(const DexFile& dex_file, uint32_t i);
    244   void CreateCallSiteId(const DexFile& dex_file, uint32_t i);
    245   void CreateMethodHandleItem(const DexFile& dex_file, uint32_t i);
    246 
    247   void CreateCallSitesAndMethodHandles(const DexFile& dex_file);
    248 
    249   TypeList* CreateTypeList(const DexFile::TypeList* type_list, uint32_t offset);
    250   EncodedArrayItem* CreateEncodedArrayItem(const DexFile& dex_file,
    251                                            const uint8_t* static_data,
    252                                            uint32_t offset);
    253   AnnotationItem* CreateAnnotationItem(const DexFile& dex_file,
    254                                        const DexFile::AnnotationItem* annotation);
    255   AnnotationSetItem* CreateAnnotationSetItem(const DexFile& dex_file,
    256       const DexFile::AnnotationSetItem* disk_annotations_item, uint32_t offset);
    257   AnnotationsDirectoryItem* CreateAnnotationsDirectoryItem(const DexFile& dex_file,
    258       const DexFile::AnnotationsDirectoryItem* disk_annotations_item, uint32_t offset);
    259   CodeItem* DedupeOrCreateCodeItem(const DexFile& dex_file,
    260                                    const DexFile::CodeItem* disk_code_item,
    261                                    uint32_t offset,
    262                                    uint32_t dex_method_index);
    263   ClassData* CreateClassData(const DexFile& dex_file, const uint8_t* encoded_data, uint32_t offset);
    264   void AddAnnotationsFromMapListSection(const DexFile& dex_file,
    265                                         uint32_t start_offset,
    266                                         uint32_t count);
    267 
    268   StringId* GetStringId(uint32_t index) {
    269     CHECK_LT(index, StringIdsSize());
    270     return StringIds()[index].get();
    271   }
    272   TypeId* GetTypeId(uint32_t index) {
    273     CHECK_LT(index, TypeIdsSize());
    274     return TypeIds()[index].get();
    275   }
    276   ProtoId* GetProtoId(uint32_t index) {
    277     CHECK_LT(index, ProtoIdsSize());
    278     return ProtoIds()[index].get();
    279   }
    280   FieldId* GetFieldId(uint32_t index) {
    281     CHECK_LT(index, FieldIdsSize());
    282     return FieldIds()[index].get();
    283   }
    284   MethodId* GetMethodId(uint32_t index) {
    285     CHECK_LT(index, MethodIdsSize());
    286     return MethodIds()[index].get();
    287   }
    288   ClassDef* GetClassDef(uint32_t index) {
    289     CHECK_LT(index, ClassDefsSize());
    290     return ClassDefs()[index].get();
    291   }
    292   CallSiteId* GetCallSiteId(uint32_t index) {
    293     CHECK_LT(index, CallSiteIdsSize());
    294     return CallSiteIds()[index].get();
    295   }
    296   MethodHandleItem* GetMethodHandle(uint32_t index) {
    297     CHECK_LT(index, MethodHandleItemsSize());
    298     return MethodHandleItems()[index].get();
    299   }
    300 
    301   StringId* GetStringIdOrNullPtr(uint32_t index) {
    302     return index == dex::kDexNoIndex ? nullptr : GetStringId(index);
    303   }
    304   TypeId* GetTypeIdOrNullPtr(uint16_t index) {
    305     return index == DexFile::kDexNoIndex16 ? nullptr : GetTypeId(index);
    306   }
    307 
    308   uint32_t StringIdsOffset() const { return string_ids_.GetOffset(); }
    309   uint32_t TypeIdsOffset() const { return type_ids_.GetOffset(); }
    310   uint32_t ProtoIdsOffset() const { return proto_ids_.GetOffset(); }
    311   uint32_t FieldIdsOffset() const { return field_ids_.GetOffset(); }
    312   uint32_t MethodIdsOffset() const { return method_ids_.GetOffset(); }
    313   uint32_t ClassDefsOffset() const { return class_defs_.GetOffset(); }
    314   uint32_t CallSiteIdsOffset() const { return call_site_ids_.GetOffset(); }
    315   uint32_t MethodHandleItemsOffset() const { return method_handle_items_.GetOffset(); }
    316   uint32_t StringDatasOffset() const { return string_datas_.GetOffset(); }
    317   uint32_t TypeListsOffset() const { return type_lists_.GetOffset(); }
    318   uint32_t EncodedArrayItemsOffset() const { return encoded_array_items_.GetOffset(); }
    319   uint32_t AnnotationItemsOffset() const { return annotation_items_.GetOffset(); }
    320   uint32_t AnnotationSetItemsOffset() const { return annotation_set_items_.GetOffset(); }
    321   uint32_t AnnotationSetRefListsOffset() const { return annotation_set_ref_lists_.GetOffset(); }
    322   uint32_t AnnotationsDirectoryItemsOffset() const
    323       { return annotations_directory_items_.GetOffset(); }
    324   uint32_t DebugInfoItemsOffset() const { return debug_info_items_.GetOffset(); }
    325   uint32_t CodeItemsOffset() const { return code_items_.GetOffset(); }
    326   uint32_t ClassDatasOffset() const { return class_datas_.GetOffset(); }
    327   uint32_t MapListOffset() const { return map_list_offset_; }
    328 
    329   void SetStringIdsOffset(uint32_t new_offset) { string_ids_.SetOffset(new_offset); }
    330   void SetTypeIdsOffset(uint32_t new_offset) { type_ids_.SetOffset(new_offset); }
    331   void SetProtoIdsOffset(uint32_t new_offset) { proto_ids_.SetOffset(new_offset); }
    332   void SetFieldIdsOffset(uint32_t new_offset) { field_ids_.SetOffset(new_offset); }
    333   void SetMethodIdsOffset(uint32_t new_offset) { method_ids_.SetOffset(new_offset); }
    334   void SetClassDefsOffset(uint32_t new_offset) { class_defs_.SetOffset(new_offset); }
    335   void SetCallSiteIdsOffset(uint32_t new_offset) { call_site_ids_.SetOffset(new_offset); }
    336   void SetMethodHandleItemsOffset(uint32_t new_offset)
    337       { method_handle_items_.SetOffset(new_offset); }
    338   void SetStringDatasOffset(uint32_t new_offset) { string_datas_.SetOffset(new_offset); }
    339   void SetTypeListsOffset(uint32_t new_offset) { type_lists_.SetOffset(new_offset); }
    340   void SetEncodedArrayItemsOffset(uint32_t new_offset)
    341       { encoded_array_items_.SetOffset(new_offset); }
    342   void SetAnnotationItemsOffset(uint32_t new_offset) { annotation_items_.SetOffset(new_offset); }
    343   void SetAnnotationSetItemsOffset(uint32_t new_offset)
    344       { annotation_set_items_.SetOffset(new_offset); }
    345   void SetAnnotationSetRefListsOffset(uint32_t new_offset)
    346       { annotation_set_ref_lists_.SetOffset(new_offset); }
    347   void SetAnnotationsDirectoryItemsOffset(uint32_t new_offset)
    348       { annotations_directory_items_.SetOffset(new_offset); }
    349   void SetDebugInfoItemsOffset(uint32_t new_offset) { debug_info_items_.SetOffset(new_offset); }
    350   void SetCodeItemsOffset(uint32_t new_offset) { code_items_.SetOffset(new_offset); }
    351   void SetClassDatasOffset(uint32_t new_offset) { class_datas_.SetOffset(new_offset); }
    352   void SetMapListOffset(uint32_t new_offset) { map_list_offset_ = new_offset; }
    353 
    354   uint32_t StringIdsSize() const { return string_ids_.Size(); }
    355   uint32_t TypeIdsSize() const { return type_ids_.Size(); }
    356   uint32_t ProtoIdsSize() const { return proto_ids_.Size(); }
    357   uint32_t FieldIdsSize() const { return field_ids_.Size(); }
    358   uint32_t MethodIdsSize() const { return method_ids_.Size(); }
    359   uint32_t ClassDefsSize() const { return class_defs_.Size(); }
    360   uint32_t CallSiteIdsSize() const { return call_site_ids_.Size(); }
    361   uint32_t MethodHandleItemsSize() const { return method_handle_items_.Size(); }
    362   uint32_t StringDatasSize() const { return string_datas_.Size(); }
    363   uint32_t TypeListsSize() const { return type_lists_.Size(); }
    364   uint32_t EncodedArrayItemsSize() const { return encoded_array_items_.Size(); }
    365   uint32_t AnnotationItemsSize() const { return annotation_items_.Size(); }
    366   uint32_t AnnotationSetItemsSize() const { return annotation_set_items_.Size(); }
    367   uint32_t AnnotationSetRefListsSize() const { return annotation_set_ref_lists_.Size(); }
    368   uint32_t AnnotationsDirectoryItemsSize() const { return annotations_directory_items_.Size(); }
    369   uint32_t DebugInfoItemsSize() const { return debug_info_items_.Size(); }
    370   uint32_t CodeItemsSize() const { return code_items_.Size(); }
    371   uint32_t ClassDatasSize() const { return class_datas_.Size(); }
    372 
    373   // Sort the vectors buy map order (same order that was used in the input file).
    374   void SortVectorsByMapOrder();
    375 
    376   template <typename Type>
    377   void AddItem(CollectionMap<Type>& map,
    378                CollectionVector<Type>& vector,
    379                Type* item,
    380                uint32_t offset) {
    381     DCHECK(!map.GetExistingObject(offset));
    382     DCHECK(!item->OffsetAssigned());
    383     if (eagerly_assign_offsets_) {
    384       item->SetOffset(offset);
    385     }
    386     map.AddItem(item, offset);
    387     vector.AddItem(item);
    388   }
    389 
    390   template <typename Type>
    391   void AddIndexedItem(IndexedCollectionVector<Type>& vector,
    392                       Type* item,
    393                       uint32_t offset,
    394                       uint32_t index) {
    395     DCHECK(!item->OffsetAssigned());
    396     if (eagerly_assign_offsets_) {
    397       item->SetOffset(offset);
    398     }
    399     vector.AddIndexedItem(item, index);
    400   }
    401 
    402   void SetEagerlyAssignOffsets(bool eagerly_assign_offsets) {
    403     eagerly_assign_offsets_ = eagerly_assign_offsets;
    404   }
    405 
    406   void SetLinkData(std::vector<uint8_t>&& link_data) {
    407     link_data_ = std::move(link_data);
    408   }
    409 
    410   const std::vector<uint8_t>& LinkData() const {
    411     return link_data_;
    412   }
    413 
    414  private:
    415   EncodedValue* ReadEncodedValue(const DexFile& dex_file, const uint8_t** data);
    416   EncodedValue* ReadEncodedValue(const DexFile& dex_file,
    417                                  const uint8_t** data,
    418                                  uint8_t type,
    419                                  uint8_t length);
    420   void ReadEncodedValue(const DexFile& dex_file,
    421                         const uint8_t** data,
    422                         uint8_t type,
    423                         uint8_t length,
    424                         EncodedValue* item);
    425 
    426   ParameterAnnotation* GenerateParameterAnnotation(const DexFile& dex_file, MethodId* method_id,
    427       const DexFile::AnnotationSetRefList* annotation_set_ref_list, uint32_t offset);
    428   MethodItem* GenerateMethodItem(const DexFile& dex_file, ClassDataItemIterator& cdii);
    429 
    430   // Collection vectors own the IR data.
    431   IndexedCollectionVector<StringId> string_ids_;
    432   IndexedCollectionVector<TypeId> type_ids_;
    433   IndexedCollectionVector<ProtoId> proto_ids_;
    434   IndexedCollectionVector<FieldId> field_ids_;
    435   IndexedCollectionVector<MethodId> method_ids_;
    436   IndexedCollectionVector<CallSiteId> call_site_ids_;
    437   IndexedCollectionVector<MethodHandleItem> method_handle_items_;
    438   IndexedCollectionVector<StringData> string_datas_;
    439   IndexedCollectionVector<TypeList> type_lists_;
    440   IndexedCollectionVector<EncodedArrayItem> encoded_array_items_;
    441   IndexedCollectionVector<AnnotationItem> annotation_items_;
    442   IndexedCollectionVector<AnnotationSetItem> annotation_set_items_;
    443   IndexedCollectionVector<AnnotationSetRefList> annotation_set_ref_lists_;
    444   IndexedCollectionVector<AnnotationsDirectoryItem> annotations_directory_items_;
    445   IndexedCollectionVector<ClassDef> class_defs_;
    446   // The order of the vectors controls the layout of the output file by index order, to change the
    447   // layout just sort the vector. Note that you may only change the order of the non indexed vectors
    448   // below. Indexed vectors are accessed by indices in other places, changing the sorting order will
    449   // invalidate the existing indices and is not currently supported.
    450   CollectionVector<DebugInfoItem> debug_info_items_;
    451   CollectionVector<CodeItem> code_items_;
    452   CollectionVector<ClassData> class_datas_;
    453 
    454   // Note that the maps do not have ownership, the vectors do.
    455   // TODO: These maps should only be required for building the IR and should be put in a separate
    456   // IR builder class.
    457   CollectionMap<StringData> string_datas_map_;
    458   CollectionMap<TypeList> type_lists_map_;
    459   CollectionMap<EncodedArrayItem> encoded_array_items_map_;
    460   CollectionMap<AnnotationItem> annotation_items_map_;
    461   CollectionMap<AnnotationSetItem> annotation_set_items_map_;
    462   CollectionMap<AnnotationSetRefList> annotation_set_ref_lists_map_;
    463   CollectionMap<AnnotationsDirectoryItem> annotations_directory_items_map_;
    464   CollectionMap<DebugInfoItem> debug_info_items_map_;
    465   // Code item maps need to check both the debug info offset and debug info offset, do not use
    466   // CollectionMap.
    467   // First offset is the code item offset, second is the debug info offset.
    468   std::map<std::pair<uint32_t, uint32_t>, CodeItem*> code_items_map_;
    469   CollectionMap<ClassData> class_datas_map_;
    470 
    471   uint32_t map_list_offset_ = 0;
    472 
    473   // Link data.
    474   std::vector<uint8_t> link_data_;
    475 
    476   // If we eagerly assign offsets during IR building or later after layout. Must be false if
    477   // changing the layout is enabled.
    478   bool eagerly_assign_offsets_;
    479 
    480   DISALLOW_COPY_AND_ASSIGN(Collections);
    481 };
    482 
    483 class Item {
    484  public:
    485   Item() { }
    486   virtual ~Item() { }
    487 
    488   // Return the assigned offset.
    489   uint32_t GetOffset() const WARN_UNUSED {
    490     CHECK(OffsetAssigned());
    491     return offset_;
    492   }
    493   uint32_t GetSize() const WARN_UNUSED { return size_; }
    494   void SetOffset(uint32_t offset) { offset_ = offset; }
    495   void SetSize(uint32_t size) { size_ = size; }
    496   bool OffsetAssigned() const {
    497     return offset_ != kOffsetUnassigned;
    498   }
    499 
    500  protected:
    501   Item(uint32_t offset, uint32_t size) : offset_(offset), size_(size) { }
    502 
    503   // 0 is the dex file header and shouldn't be a valid offset for any part of the dex file.
    504   static constexpr uint32_t kOffsetUnassigned = 0u;
    505 
    506   // Start out unassigned.
    507   uint32_t offset_ = kOffsetUnassigned;
    508   uint32_t size_ = 0;
    509 };
    510 
    511 class IndexedItem : public Item {
    512  public:
    513   IndexedItem() { }
    514   virtual ~IndexedItem() { }
    515 
    516   uint32_t GetIndex() const { return index_; }
    517   void SetIndex(uint32_t index) { index_ = index; }
    518 
    519  protected:
    520   IndexedItem(uint32_t offset, uint32_t size, uint32_t index)
    521       : Item(offset, size), index_(index) { }
    522 
    523   uint32_t index_ = 0;
    524 };
    525 
    526 class Header : public Item {
    527  public:
    528   Header(const uint8_t* magic,
    529          uint32_t checksum,
    530          const uint8_t* signature,
    531          uint32_t endian_tag,
    532          uint32_t file_size,
    533          uint32_t header_size,
    534          uint32_t link_size,
    535          uint32_t link_offset,
    536          uint32_t data_size,
    537          uint32_t data_offset,
    538          bool support_default_methods)
    539       : Item(0, kHeaderItemSize),
    540         checksum_(checksum),
    541         endian_tag_(endian_tag),
    542         file_size_(file_size),
    543         header_size_(header_size),
    544         link_size_(link_size),
    545         link_offset_(link_offset),
    546         data_size_(data_size),
    547         data_offset_(data_offset),
    548         support_default_methods_(support_default_methods) {
    549     memcpy(magic_, magic, sizeof(magic_));
    550     memcpy(signature_, signature, sizeof(signature_));
    551   }
    552   ~Header() OVERRIDE { }
    553 
    554   static size_t ItemSize() { return kHeaderItemSize; }
    555 
    556   const uint8_t* Magic() const { return magic_; }
    557   uint32_t Checksum() const { return checksum_; }
    558   const uint8_t* Signature() const { return signature_; }
    559   uint32_t EndianTag() const { return endian_tag_; }
    560   uint32_t FileSize() const { return file_size_; }
    561   uint32_t HeaderSize() const { return header_size_; }
    562   uint32_t LinkSize() const { return link_size_; }
    563   uint32_t LinkOffset() const { return link_offset_; }
    564   uint32_t DataSize() const { return data_size_; }
    565   uint32_t DataOffset() const { return data_offset_; }
    566 
    567   void SetChecksum(uint32_t new_checksum) { checksum_ = new_checksum; }
    568   void SetSignature(const uint8_t* new_signature) {
    569     memcpy(signature_, new_signature, sizeof(signature_));
    570   }
    571   void SetFileSize(uint32_t new_file_size) { file_size_ = new_file_size; }
    572   void SetHeaderSize(uint32_t new_header_size) { header_size_ = new_header_size; }
    573   void SetLinkSize(uint32_t new_link_size) { link_size_ = new_link_size; }
    574   void SetLinkOffset(uint32_t new_link_offset) { link_offset_ = new_link_offset; }
    575   void SetDataSize(uint32_t new_data_size) { data_size_ = new_data_size; }
    576   void SetDataOffset(uint32_t new_data_offset) { data_offset_ = new_data_offset; }
    577 
    578   Collections& GetCollections() { return collections_; }
    579 
    580   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
    581 
    582   bool SupportDefaultMethods() const {
    583     return support_default_methods_;
    584   }
    585 
    586  private:
    587   uint8_t magic_[8];
    588   uint32_t checksum_;
    589   uint8_t signature_[DexFile::kSha1DigestSize];
    590   uint32_t endian_tag_;
    591   uint32_t file_size_;
    592   uint32_t header_size_;
    593   uint32_t link_size_;
    594   uint32_t link_offset_;
    595   uint32_t data_size_;
    596   uint32_t data_offset_;
    597   const bool support_default_methods_;
    598 
    599   Collections collections_;
    600 
    601   DISALLOW_COPY_AND_ASSIGN(Header);
    602 };
    603 
    604 class StringData : public Item {
    605  public:
    606   explicit StringData(const char* data) : data_(strdup(data)) {
    607     size_ = UnsignedLeb128Size(CountModifiedUtf8Chars(data)) + strlen(data);
    608   }
    609 
    610   const char* Data() const { return data_.get(); }
    611 
    612   void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
    613 
    614  private:
    615   UniqueCPtr<const char> data_;
    616 
    617   DISALLOW_COPY_AND_ASSIGN(StringData);
    618 };
    619 
    620 class StringId : public IndexedItem {
    621  public:
    622   explicit StringId(StringData* string_data) : string_data_(string_data) {
    623     size_ = kStringIdItemSize;
    624   }
    625   ~StringId() OVERRIDE { }
    626 
    627   static size_t ItemSize() { return kStringIdItemSize; }
    628 
    629   const char* Data() const { return string_data_->Data(); }
    630   StringData* DataItem() const { return string_data_; }
    631 
    632   void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
    633 
    634  private:
    635   StringData* string_data_;
    636 
    637   DISALLOW_COPY_AND_ASSIGN(StringId);
    638 };
    639 
    640 class TypeId : public IndexedItem {
    641  public:
    642   explicit TypeId(StringId* string_id) : string_id_(string_id) { size_ = kTypeIdItemSize; }
    643   ~TypeId() OVERRIDE { }
    644 
    645   static size_t ItemSize() { return kTypeIdItemSize; }
    646 
    647   StringId* GetStringId() const { return string_id_; }
    648 
    649   void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
    650 
    651  private:
    652   StringId* string_id_;
    653 
    654   DISALLOW_COPY_AND_ASSIGN(TypeId);
    655 };
    656 
    657 using TypeIdVector = std::vector<const TypeId*>;
    658 
    659 class TypeList : public Item {
    660  public:
    661   explicit TypeList(TypeIdVector* type_list) : type_list_(type_list) {
    662     size_ = sizeof(uint32_t) + (type_list->size() * sizeof(uint16_t));
    663   }
    664   ~TypeList() OVERRIDE { }
    665 
    666   const TypeIdVector* GetTypeList() const { return type_list_.get(); }
    667 
    668  private:
    669   std::unique_ptr<TypeIdVector> type_list_;
    670 
    671   DISALLOW_COPY_AND_ASSIGN(TypeList);
    672 };
    673 
    674 class ProtoId : public IndexedItem {
    675  public:
    676   ProtoId(const StringId* shorty, const TypeId* return_type, TypeList* parameters)
    677       : shorty_(shorty), return_type_(return_type), parameters_(parameters)
    678       { size_ = kProtoIdItemSize; }
    679   ~ProtoId() OVERRIDE { }
    680 
    681   static size_t ItemSize() { return kProtoIdItemSize; }
    682 
    683   const StringId* Shorty() const { return shorty_; }
    684   const TypeId* ReturnType() const { return return_type_; }
    685   const TypeList* Parameters() const { return parameters_; }
    686 
    687   void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
    688 
    689  private:
    690   const StringId* shorty_;
    691   const TypeId* return_type_;
    692   TypeList* parameters_;  // This can be nullptr.
    693 
    694   DISALLOW_COPY_AND_ASSIGN(ProtoId);
    695 };
    696 
    697 class FieldId : public IndexedItem {
    698  public:
    699   FieldId(const TypeId* klass, const TypeId* type, const StringId* name)
    700       : class_(klass), type_(type), name_(name) { size_ = kFieldIdItemSize; }
    701   ~FieldId() OVERRIDE { }
    702 
    703   static size_t ItemSize() { return kFieldIdItemSize; }
    704 
    705   const TypeId* Class() const { return class_; }
    706   const TypeId* Type() const { return type_; }
    707   const StringId* Name() const { return name_; }
    708 
    709   void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
    710 
    711  private:
    712   const TypeId* class_;
    713   const TypeId* type_;
    714   const StringId* name_;
    715 
    716   DISALLOW_COPY_AND_ASSIGN(FieldId);
    717 };
    718 
    719 class MethodId : public IndexedItem {
    720  public:
    721   MethodId(const TypeId* klass, const ProtoId* proto, const StringId* name)
    722       : class_(klass), proto_(proto), name_(name) { size_ = kMethodIdItemSize; }
    723   ~MethodId() OVERRIDE { }
    724 
    725   static size_t ItemSize() { return kMethodIdItemSize; }
    726 
    727   const TypeId* Class() const { return class_; }
    728   const ProtoId* Proto() const { return proto_; }
    729   const StringId* Name() const { return name_; }
    730 
    731   void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
    732 
    733  private:
    734   const TypeId* class_;
    735   const ProtoId* proto_;
    736   const StringId* name_;
    737 
    738   DISALLOW_COPY_AND_ASSIGN(MethodId);
    739 };
    740 
    741 class FieldItem : public Item {
    742  public:
    743   FieldItem(uint32_t access_flags, const FieldId* field_id)
    744       : access_flags_(access_flags), field_id_(field_id) { }
    745   ~FieldItem() OVERRIDE { }
    746 
    747   uint32_t GetAccessFlags() const { return access_flags_; }
    748   const FieldId* GetFieldId() const { return field_id_; }
    749 
    750   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
    751 
    752  private:
    753   uint32_t access_flags_;
    754   const FieldId* field_id_;
    755 
    756   DISALLOW_COPY_AND_ASSIGN(FieldItem);
    757 };
    758 
    759 using FieldItemVector = std::vector<std::unique_ptr<FieldItem>>;
    760 
    761 class MethodItem : public Item {
    762  public:
    763   MethodItem(uint32_t access_flags, const MethodId* method_id, CodeItem* code)
    764       : access_flags_(access_flags), method_id_(method_id), code_(code) { }
    765   ~MethodItem() OVERRIDE { }
    766 
    767   uint32_t GetAccessFlags() const { return access_flags_; }
    768   const MethodId* GetMethodId() const { return method_id_; }
    769   CodeItem* GetCodeItem() { return code_; }
    770 
    771   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
    772 
    773  private:
    774   uint32_t access_flags_;
    775   const MethodId* method_id_;
    776   CodeItem* code_;  // This can be nullptr.
    777 
    778   DISALLOW_COPY_AND_ASSIGN(MethodItem);
    779 };
    780 
    781 using MethodItemVector = std::vector<std::unique_ptr<MethodItem>>;
    782 
    783 class EncodedValue {
    784  public:
    785   explicit EncodedValue(uint8_t type) : type_(type) { }
    786 
    787   int8_t Type() const { return type_; }
    788 
    789   void SetBoolean(bool z) { u_.bool_val_ = z; }
    790   void SetByte(int8_t b) { u_.byte_val_ = b; }
    791   void SetShort(int16_t s) { u_.short_val_ = s; }
    792   void SetChar(uint16_t c) { u_.char_val_ = c; }
    793   void SetInt(int32_t i) { u_.int_val_ = i; }
    794   void SetLong(int64_t l) { u_.long_val_ = l; }
    795   void SetFloat(float f) { u_.float_val_ = f; }
    796   void SetDouble(double d) { u_.double_val_ = d; }
    797   void SetStringId(StringId* string_id) { u_.string_val_ = string_id; }
    798   void SetTypeId(TypeId* type_id) { u_.type_val_ = type_id; }
    799   void SetProtoId(ProtoId* proto_id) { u_.proto_val_ = proto_id; }
    800   void SetFieldId(FieldId* field_id) { u_.field_val_ = field_id; }
    801   void SetMethodId(MethodId* method_id) { u_.method_val_ = method_id; }
    802   void SetMethodHandle(MethodHandleItem* method_handle) { u_.method_handle_val_ = method_handle; }
    803   void SetEncodedArray(EncodedArrayItem* encoded_array) { encoded_array_.reset(encoded_array); }
    804   void SetEncodedAnnotation(EncodedAnnotation* encoded_annotation)
    805       { encoded_annotation_.reset(encoded_annotation); }
    806 
    807   bool GetBoolean() const { return u_.bool_val_; }
    808   int8_t GetByte() const { return u_.byte_val_; }
    809   int16_t GetShort() const { return u_.short_val_; }
    810   uint16_t GetChar() const { return u_.char_val_; }
    811   int32_t GetInt() const { return u_.int_val_; }
    812   int64_t GetLong() const { return u_.long_val_; }
    813   float GetFloat() const { return u_.float_val_; }
    814   double GetDouble() const { return u_.double_val_; }
    815   StringId* GetStringId() const { return u_.string_val_; }
    816   TypeId* GetTypeId() const { return u_.type_val_; }
    817   ProtoId* GetProtoId() const { return u_.proto_val_; }
    818   FieldId* GetFieldId() const { return u_.field_val_; }
    819   MethodId* GetMethodId() const { return u_.method_val_; }
    820   MethodHandleItem* GetMethodHandle() const { return u_.method_handle_val_; }
    821   EncodedArrayItem* GetEncodedArray() const { return encoded_array_.get(); }
    822   EncodedAnnotation* GetEncodedAnnotation() const { return encoded_annotation_.get(); }
    823 
    824   EncodedAnnotation* ReleaseEncodedAnnotation() { return encoded_annotation_.release(); }
    825 
    826  private:
    827   uint8_t type_;
    828   union {
    829     bool bool_val_;
    830     int8_t byte_val_;
    831     int16_t short_val_;
    832     uint16_t char_val_;
    833     int32_t int_val_;
    834     int64_t long_val_;
    835     float float_val_;
    836     double double_val_;
    837     StringId* string_val_;
    838     TypeId* type_val_;
    839     ProtoId* proto_val_;
    840     FieldId* field_val_;
    841     MethodId* method_val_;
    842     MethodHandleItem* method_handle_val_;
    843   } u_;
    844   std::unique_ptr<EncodedArrayItem> encoded_array_;
    845   std::unique_ptr<EncodedAnnotation> encoded_annotation_;
    846 
    847   DISALLOW_COPY_AND_ASSIGN(EncodedValue);
    848 };
    849 
    850 using EncodedValueVector = std::vector<std::unique_ptr<EncodedValue>>;
    851 
    852 class AnnotationElement {
    853  public:
    854   AnnotationElement(StringId* name, EncodedValue* value) : name_(name), value_(value) { }
    855 
    856   StringId* GetName() const { return name_; }
    857   EncodedValue* GetValue() const { return value_.get(); }
    858 
    859  private:
    860   StringId* name_;
    861   std::unique_ptr<EncodedValue> value_;
    862 
    863   DISALLOW_COPY_AND_ASSIGN(AnnotationElement);
    864 };
    865 
    866 using AnnotationElementVector = std::vector<std::unique_ptr<AnnotationElement>>;
    867 
    868 class EncodedAnnotation {
    869  public:
    870   EncodedAnnotation(TypeId* type, AnnotationElementVector* elements)
    871       : type_(type), elements_(elements) { }
    872 
    873   TypeId* GetType() const { return type_; }
    874   AnnotationElementVector* GetAnnotationElements() const { return elements_.get(); }
    875 
    876  private:
    877   TypeId* type_;
    878   std::unique_ptr<AnnotationElementVector> elements_;
    879 
    880   DISALLOW_COPY_AND_ASSIGN(EncodedAnnotation);
    881 };
    882 
    883 class EncodedArrayItem : public Item {
    884  public:
    885   explicit EncodedArrayItem(EncodedValueVector* encoded_values)
    886       : encoded_values_(encoded_values) { }
    887 
    888   EncodedValueVector* GetEncodedValues() const { return encoded_values_.get(); }
    889 
    890  private:
    891   std::unique_ptr<EncodedValueVector> encoded_values_;
    892 
    893   DISALLOW_COPY_AND_ASSIGN(EncodedArrayItem);
    894 };
    895 
    896 class ClassData : public Item {
    897  public:
    898   ClassData(FieldItemVector* static_fields,
    899             FieldItemVector* instance_fields,
    900             MethodItemVector* direct_methods,
    901             MethodItemVector* virtual_methods)
    902       : static_fields_(static_fields),
    903         instance_fields_(instance_fields),
    904         direct_methods_(direct_methods),
    905         virtual_methods_(virtual_methods) { }
    906 
    907   ~ClassData() OVERRIDE = default;
    908   FieldItemVector* StaticFields() { return static_fields_.get(); }
    909   FieldItemVector* InstanceFields() { return instance_fields_.get(); }
    910   MethodItemVector* DirectMethods() { return direct_methods_.get(); }
    911   MethodItemVector* VirtualMethods() { return virtual_methods_.get(); }
    912 
    913   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
    914 
    915  private:
    916   std::unique_ptr<FieldItemVector> static_fields_;
    917   std::unique_ptr<FieldItemVector> instance_fields_;
    918   std::unique_ptr<MethodItemVector> direct_methods_;
    919   std::unique_ptr<MethodItemVector> virtual_methods_;
    920 
    921   DISALLOW_COPY_AND_ASSIGN(ClassData);
    922 };
    923 
    924 class ClassDef : public IndexedItem {
    925  public:
    926   ClassDef(const TypeId* class_type,
    927            uint32_t access_flags,
    928            const TypeId* superclass,
    929            TypeList* interfaces,
    930            const StringId* source_file,
    931            AnnotationsDirectoryItem* annotations,
    932            EncodedArrayItem* static_values,
    933            ClassData* class_data)
    934       : class_type_(class_type),
    935         access_flags_(access_flags),
    936         superclass_(superclass),
    937         interfaces_(interfaces),
    938         source_file_(source_file),
    939         annotations_(annotations),
    940         class_data_(class_data),
    941         static_values_(static_values) { size_ = kClassDefItemSize; }
    942 
    943   ~ClassDef() OVERRIDE { }
    944 
    945   static size_t ItemSize() { return kClassDefItemSize; }
    946 
    947   const TypeId* ClassType() const { return class_type_; }
    948   uint32_t GetAccessFlags() const { return access_flags_; }
    949   const TypeId* Superclass() const { return superclass_; }
    950   const TypeList* Interfaces() { return interfaces_; }
    951   uint32_t InterfacesOffset() { return interfaces_ == nullptr ? 0 : interfaces_->GetOffset(); }
    952   const StringId* SourceFile() const { return source_file_; }
    953   AnnotationsDirectoryItem* Annotations() const { return annotations_; }
    954   ClassData* GetClassData() { return class_data_; }
    955   EncodedArrayItem* StaticValues() { return static_values_; }
    956 
    957   MethodItem* GenerateMethodItem(Header& header, ClassDataItemIterator& cdii);
    958 
    959   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
    960 
    961  private:
    962   const TypeId* class_type_;
    963   uint32_t access_flags_;
    964   const TypeId* superclass_;  // This can be nullptr.
    965   TypeList* interfaces_;  // This can be nullptr.
    966   const StringId* source_file_;  // This can be nullptr.
    967   AnnotationsDirectoryItem* annotations_;  // This can be nullptr.
    968   ClassData* class_data_;  // This can be nullptr.
    969   EncodedArrayItem* static_values_;  // This can be nullptr.
    970 
    971   DISALLOW_COPY_AND_ASSIGN(ClassDef);
    972 };
    973 
    974 class TypeAddrPair {
    975  public:
    976   TypeAddrPair(const TypeId* type_id, uint32_t address) : type_id_(type_id), address_(address) { }
    977 
    978   const TypeId* GetTypeId() const { return type_id_; }
    979   uint32_t GetAddress() const { return address_; }
    980 
    981  private:
    982   const TypeId* type_id_;  // This can be nullptr.
    983   uint32_t address_;
    984 
    985   DISALLOW_COPY_AND_ASSIGN(TypeAddrPair);
    986 };
    987 
    988 using TypeAddrPairVector = std::vector<std::unique_ptr<const TypeAddrPair>>;
    989 
    990 class CatchHandler {
    991  public:
    992   explicit CatchHandler(bool catch_all, uint16_t list_offset, TypeAddrPairVector* handlers)
    993       : catch_all_(catch_all), list_offset_(list_offset), handlers_(handlers) { }
    994 
    995   bool HasCatchAll() const { return catch_all_; }
    996   uint16_t GetListOffset() const { return list_offset_; }
    997   TypeAddrPairVector* GetHandlers() const { return handlers_.get(); }
    998 
    999  private:
   1000   bool catch_all_;
   1001   uint16_t list_offset_;
   1002   std::unique_ptr<TypeAddrPairVector> handlers_;
   1003 
   1004   DISALLOW_COPY_AND_ASSIGN(CatchHandler);
   1005 };
   1006 
   1007 using CatchHandlerVector = std::vector<std::unique_ptr<const CatchHandler>>;
   1008 
   1009 class TryItem : public Item {
   1010  public:
   1011   TryItem(uint32_t start_addr, uint16_t insn_count, const CatchHandler* handlers)
   1012       : start_addr_(start_addr), insn_count_(insn_count), handlers_(handlers) { }
   1013   ~TryItem() OVERRIDE { }
   1014 
   1015   uint32_t StartAddr() const { return start_addr_; }
   1016   uint16_t InsnCount() const { return insn_count_; }
   1017   const CatchHandler* GetHandlers() const { return handlers_; }
   1018 
   1019   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
   1020 
   1021  private:
   1022   uint32_t start_addr_;
   1023   uint16_t insn_count_;
   1024   const CatchHandler* handlers_;
   1025 
   1026   DISALLOW_COPY_AND_ASSIGN(TryItem);
   1027 };
   1028 
   1029 using TryItemVector = std::vector<std::unique_ptr<const TryItem>>;
   1030 
   1031 class CodeFixups {
   1032  public:
   1033   CodeFixups(std::vector<TypeId*> type_ids,
   1034              std::vector<StringId*> string_ids,
   1035              std::vector<MethodId*> method_ids,
   1036              std::vector<FieldId*> field_ids)
   1037       : type_ids_(std::move(type_ids)),
   1038         string_ids_(std::move(string_ids)),
   1039         method_ids_(std::move(method_ids)),
   1040         field_ids_(std::move(field_ids)) { }
   1041 
   1042   const std::vector<TypeId*>& TypeIds() const { return type_ids_; }
   1043   const std::vector<StringId*>& StringIds() const { return string_ids_; }
   1044   const std::vector<MethodId*>& MethodIds() const { return method_ids_; }
   1045   const std::vector<FieldId*>& FieldIds() const { return field_ids_; }
   1046 
   1047  private:
   1048   std::vector<TypeId*> type_ids_;
   1049   std::vector<StringId*> string_ids_;
   1050   std::vector<MethodId*> method_ids_;
   1051   std::vector<FieldId*> field_ids_;
   1052 
   1053   DISALLOW_COPY_AND_ASSIGN(CodeFixups);
   1054 };
   1055 
   1056 class CodeItem : public Item {
   1057  public:
   1058   CodeItem(uint16_t registers_size,
   1059            uint16_t ins_size,
   1060            uint16_t outs_size,
   1061            DebugInfoItem* debug_info,
   1062            uint32_t insns_size,
   1063            uint16_t* insns,
   1064            TryItemVector* tries,
   1065            CatchHandlerVector* handlers)
   1066       : registers_size_(registers_size),
   1067         ins_size_(ins_size),
   1068         outs_size_(outs_size),
   1069         debug_info_(debug_info),
   1070         insns_size_(insns_size),
   1071         insns_(insns),
   1072         tries_(tries),
   1073         handlers_(handlers) { }
   1074 
   1075   ~CodeItem() OVERRIDE { }
   1076 
   1077   uint16_t RegistersSize() const { return registers_size_; }
   1078   uint16_t InsSize() const { return ins_size_; }
   1079   uint16_t OutsSize() const { return outs_size_; }
   1080   uint16_t TriesSize() const { return tries_ == nullptr ? 0 : tries_->size(); }
   1081   DebugInfoItem* DebugInfo() const { return debug_info_; }
   1082   uint32_t InsnsSize() const { return insns_size_; }
   1083   uint16_t* Insns() const { return insns_.get(); }
   1084   TryItemVector* Tries() const { return tries_.get(); }
   1085   CatchHandlerVector* Handlers() const { return handlers_.get(); }
   1086 
   1087   void SetCodeFixups(CodeFixups* fixups) { fixups_.reset(fixups); }
   1088   CodeFixups* GetCodeFixups() const { return fixups_.get(); }
   1089 
   1090   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
   1091 
   1092   IterationRange<DexInstructionIterator> Instructions() const {
   1093     return MakeIterationRange(DexInstructionIterator(Insns(), 0u),
   1094                               DexInstructionIterator(Insns(), InsnsSize()));
   1095   }
   1096 
   1097  private:
   1098   uint16_t registers_size_;
   1099   uint16_t ins_size_;
   1100   uint16_t outs_size_;
   1101   DebugInfoItem* debug_info_;  // This can be nullptr.
   1102   uint32_t insns_size_;
   1103   std::unique_ptr<uint16_t[]> insns_;
   1104   std::unique_ptr<TryItemVector> tries_;  // This can be nullptr.
   1105   std::unique_ptr<CatchHandlerVector> handlers_;  // This can be nullptr.
   1106   std::unique_ptr<CodeFixups> fixups_;  // This can be nullptr.
   1107 
   1108   DISALLOW_COPY_AND_ASSIGN(CodeItem);
   1109 };
   1110 
   1111 class DebugInfoItem : public Item {
   1112  public:
   1113   DebugInfoItem(uint32_t debug_info_size, uint8_t* debug_info)
   1114      : debug_info_size_(debug_info_size), debug_info_(debug_info) { }
   1115 
   1116   uint32_t GetDebugInfoSize() const { return debug_info_size_; }
   1117   uint8_t* GetDebugInfo() const { return debug_info_.get(); }
   1118 
   1119  private:
   1120   uint32_t debug_info_size_;
   1121   std::unique_ptr<uint8_t[]> debug_info_;
   1122 
   1123   DISALLOW_COPY_AND_ASSIGN(DebugInfoItem);
   1124 };
   1125 
   1126 class AnnotationItem : public Item {
   1127  public:
   1128   AnnotationItem(uint8_t visibility, EncodedAnnotation* annotation)
   1129       : visibility_(visibility), annotation_(annotation) { }
   1130 
   1131   uint8_t GetVisibility() const { return visibility_; }
   1132   EncodedAnnotation* GetAnnotation() const { return annotation_.get(); }
   1133 
   1134   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
   1135 
   1136  private:
   1137   uint8_t visibility_;
   1138   std::unique_ptr<EncodedAnnotation> annotation_;
   1139 
   1140   DISALLOW_COPY_AND_ASSIGN(AnnotationItem);
   1141 };
   1142 
   1143 class AnnotationSetItem : public Item {
   1144  public:
   1145   explicit AnnotationSetItem(std::vector<AnnotationItem*>* items) : items_(items) {
   1146     size_ = sizeof(uint32_t) + items->size() * sizeof(uint32_t);
   1147   }
   1148   ~AnnotationSetItem() OVERRIDE { }
   1149 
   1150   std::vector<AnnotationItem*>* GetItems() { return items_.get(); }
   1151 
   1152   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
   1153 
   1154  private:
   1155   std::unique_ptr<std::vector<AnnotationItem*>> items_;
   1156 
   1157   DISALLOW_COPY_AND_ASSIGN(AnnotationSetItem);
   1158 };
   1159 
   1160 class AnnotationSetRefList : public Item {
   1161  public:
   1162   explicit AnnotationSetRefList(std::vector<AnnotationSetItem*>* items) : items_(items) {
   1163     size_ = sizeof(uint32_t) + items->size() * sizeof(uint32_t);
   1164   }
   1165   ~AnnotationSetRefList() OVERRIDE { }
   1166 
   1167   std::vector<AnnotationSetItem*>* GetItems() { return items_.get(); }
   1168 
   1169   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
   1170 
   1171  private:
   1172   std::unique_ptr<std::vector<AnnotationSetItem*>> items_;  // Elements of vector can be nullptr.
   1173 
   1174   DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefList);
   1175 };
   1176 
   1177 class FieldAnnotation {
   1178  public:
   1179   FieldAnnotation(FieldId* field_id, AnnotationSetItem* annotation_set_item)
   1180       : field_id_(field_id), annotation_set_item_(annotation_set_item) { }
   1181 
   1182   FieldId* GetFieldId() const { return field_id_; }
   1183   AnnotationSetItem* GetAnnotationSetItem() const { return annotation_set_item_; }
   1184 
   1185  private:
   1186   FieldId* field_id_;
   1187   AnnotationSetItem* annotation_set_item_;
   1188 
   1189   DISALLOW_COPY_AND_ASSIGN(FieldAnnotation);
   1190 };
   1191 
   1192 using FieldAnnotationVector = std::vector<std::unique_ptr<FieldAnnotation>>;
   1193 
   1194 class MethodAnnotation {
   1195  public:
   1196   MethodAnnotation(MethodId* method_id, AnnotationSetItem* annotation_set_item)
   1197       : method_id_(method_id), annotation_set_item_(annotation_set_item) { }
   1198 
   1199   MethodId* GetMethodId() const { return method_id_; }
   1200   AnnotationSetItem* GetAnnotationSetItem() const { return annotation_set_item_; }
   1201 
   1202  private:
   1203   MethodId* method_id_;
   1204   AnnotationSetItem* annotation_set_item_;
   1205 
   1206   DISALLOW_COPY_AND_ASSIGN(MethodAnnotation);
   1207 };
   1208 
   1209 using MethodAnnotationVector = std::vector<std::unique_ptr<MethodAnnotation>>;
   1210 
   1211 class ParameterAnnotation {
   1212  public:
   1213   ParameterAnnotation(MethodId* method_id, AnnotationSetRefList* annotations)
   1214       : method_id_(method_id), annotations_(annotations) { }
   1215 
   1216   MethodId* GetMethodId() const { return method_id_; }
   1217   AnnotationSetRefList* GetAnnotations() { return annotations_; }
   1218 
   1219  private:
   1220   MethodId* method_id_;
   1221   AnnotationSetRefList* annotations_;
   1222 
   1223   DISALLOW_COPY_AND_ASSIGN(ParameterAnnotation);
   1224 };
   1225 
   1226 using ParameterAnnotationVector = std::vector<std::unique_ptr<ParameterAnnotation>>;
   1227 
   1228 class AnnotationsDirectoryItem : public Item {
   1229  public:
   1230   AnnotationsDirectoryItem(AnnotationSetItem* class_annotation,
   1231                            FieldAnnotationVector* field_annotations,
   1232                            MethodAnnotationVector* method_annotations,
   1233                            ParameterAnnotationVector* parameter_annotations)
   1234       : class_annotation_(class_annotation),
   1235         field_annotations_(field_annotations),
   1236         method_annotations_(method_annotations),
   1237         parameter_annotations_(parameter_annotations) { }
   1238 
   1239   AnnotationSetItem* GetClassAnnotation() const { return class_annotation_; }
   1240   FieldAnnotationVector* GetFieldAnnotations() { return field_annotations_.get(); }
   1241   MethodAnnotationVector* GetMethodAnnotations() { return method_annotations_.get(); }
   1242   ParameterAnnotationVector* GetParameterAnnotations() { return parameter_annotations_.get(); }
   1243 
   1244   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
   1245 
   1246  private:
   1247   AnnotationSetItem* class_annotation_;  // This can be nullptr.
   1248   std::unique_ptr<FieldAnnotationVector> field_annotations_;  // This can be nullptr.
   1249   std::unique_ptr<MethodAnnotationVector> method_annotations_;  // This can be nullptr.
   1250   std::unique_ptr<ParameterAnnotationVector> parameter_annotations_;  // This can be nullptr.
   1251 
   1252   DISALLOW_COPY_AND_ASSIGN(AnnotationsDirectoryItem);
   1253 };
   1254 
   1255 class CallSiteId : public IndexedItem {
   1256  public:
   1257   explicit CallSiteId(EncodedArrayItem* call_site_item) : call_site_item_(call_site_item) {
   1258     size_ = kCallSiteIdItemSize;
   1259   }
   1260   ~CallSiteId() OVERRIDE { }
   1261 
   1262   static size_t ItemSize() { return kCallSiteIdItemSize; }
   1263 
   1264   EncodedArrayItem* CallSiteItem() const { return call_site_item_; }
   1265 
   1266   void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
   1267 
   1268  private:
   1269   EncodedArrayItem* call_site_item_;
   1270 
   1271   DISALLOW_COPY_AND_ASSIGN(CallSiteId);
   1272 };
   1273 
   1274 class MethodHandleItem : public IndexedItem {
   1275  public:
   1276   MethodHandleItem(DexFile::MethodHandleType method_handle_type, IndexedItem* field_or_method_id)
   1277       : method_handle_type_(method_handle_type),
   1278         field_or_method_id_(field_or_method_id) {
   1279     size_ = kMethodHandleItemSize;
   1280   }
   1281   ~MethodHandleItem() OVERRIDE { }
   1282 
   1283   static size_t ItemSize() { return kMethodHandleItemSize; }
   1284 
   1285   DexFile::MethodHandleType GetMethodHandleType() const { return method_handle_type_; }
   1286   IndexedItem* GetFieldOrMethodId() const { return field_or_method_id_; }
   1287 
   1288   void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
   1289 
   1290  private:
   1291   DexFile::MethodHandleType method_handle_type_;
   1292   IndexedItem* field_or_method_id_;
   1293 
   1294   DISALLOW_COPY_AND_ASSIGN(MethodHandleItem);
   1295 };
   1296 
   1297 // TODO(sehr): implement MapList.
   1298 class MapList : public Item {
   1299  public:
   1300   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
   1301 
   1302  private:
   1303   DISALLOW_COPY_AND_ASSIGN(MapList);
   1304 };
   1305 
   1306 class MapItem : public Item {
   1307  public:
   1308   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
   1309 
   1310  private:
   1311   DISALLOW_COPY_AND_ASSIGN(MapItem);
   1312 };
   1313 
   1314 // Interface for building a vector of file sections for use by other clients.
   1315 struct DexFileSection {
   1316  public:
   1317   DexFileSection(const std::string& name, uint16_t type, uint32_t size, uint32_t offset)
   1318       : name(name), type(type), size(size), offset(offset) { }
   1319   std::string name;
   1320   // The type (DexFile::MapItemType).
   1321   uint16_t type;
   1322   // The size (in elements, not bytes).
   1323   uint32_t size;
   1324   // The byte offset from the start of the file.
   1325   uint32_t offset;
   1326 };
   1327 
   1328 enum class SortDirection {
   1329   kSortAscending,
   1330   kSortDescending
   1331 };
   1332 
   1333 std::vector<DexFileSection> GetSortedDexFileSections(dex_ir::Header* header,
   1334                                                      SortDirection direction);
   1335 
   1336 }  // namespace dex_ir
   1337 }  // namespace art
   1338 
   1339 #endif  // ART_DEXLAYOUT_DEX_IR_H_
   1340