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