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