blob: ca47b348f161bf7ce5c4d96b4dc7e7e3c751214a [file] [log] [blame]
David Sehr7629f602016-08-07 16:01:51 -07001/*
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
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070022#include <stdint.h>
23
Jeff Haoea7c6292016-11-14 18:10:16 -080024#include <map>
David Sehr7629f602016-08-07 16:01:51 -070025#include <vector>
David Sehr7629f602016-08-07 16:01:51 -070026
Andreas Gampe5678db52017-06-08 14:11:18 -070027#include "base/stl_util.h"
David Sehr9e734c72018-01-04 17:56:19 -080028#include "dex/dex_file-inl.h"
29#include "dex/dex_file_types.h"
Jeff Hao3ab96b42016-09-09 18:35:01 -070030#include "leb128.h"
Jeff Haoa8621002016-10-04 18:13:44 +000031#include "utf.h"
David Sehr7629f602016-08-07 16:01:51 -070032
33namespace art {
34namespace dex_ir {
35
36// Forward declarations for classes used in containers or pointed to.
Jeff Hao3ab96b42016-09-09 18:35:01 -070037class AnnotationItem;
David Sehr7629f602016-08-07 16:01:51 -070038class AnnotationsDirectoryItem;
39class AnnotationSetItem;
Jeff Hao3ab96b42016-09-09 18:35:01 -070040class AnnotationSetRefList;
Jeff Hao5daee902017-04-27 18:00:38 -070041class CallSiteId;
David Sehr7629f602016-08-07 16:01:51 -070042class ClassData;
43class ClassDef;
44class CodeItem;
45class DebugInfoItem;
Jeff Hao3ab96b42016-09-09 18:35:01 -070046class EncodedAnnotation;
47class EncodedArrayItem;
48class EncodedValue;
David Sehr7629f602016-08-07 16:01:51 -070049class FieldId;
50class FieldItem;
51class Header;
52class MapList;
53class MapItem;
Jeff Hao5daee902017-04-27 18:00:38 -070054class MethodHandleItem;
David Sehr7629f602016-08-07 16:01:51 -070055class MethodId;
56class MethodItem;
Jeff Hao3ab96b42016-09-09 18:35:01 -070057class ParameterAnnotation;
David Sehr7629f602016-08-07 16:01:51 -070058class ProtoId;
Jeff Hao3ab96b42016-09-09 18:35:01 -070059class StringData;
David Sehr7629f602016-08-07 16:01:51 -070060class StringId;
61class TryItem;
62class TypeId;
Jeff Hao3ab96b42016-09-09 18:35:01 -070063class TypeList;
64
65// Item size constants.
66static constexpr size_t kHeaderItemSize = 112;
67static constexpr size_t kStringIdItemSize = 4;
68static constexpr size_t kTypeIdItemSize = 4;
69static constexpr size_t kProtoIdItemSize = 12;
70static constexpr size_t kFieldIdItemSize = 8;
71static constexpr size_t kMethodIdItemSize = 8;
72static constexpr size_t kClassDefItemSize = 32;
Jeff Hao5daee902017-04-27 18:00:38 -070073static constexpr size_t kCallSiteIdItemSize = 4;
74static constexpr size_t kMethodHandleItemSize = 8;
David Sehr7629f602016-08-07 16:01:51 -070075
76// Visitor support
77class AbstractDispatcher {
78 public:
79 AbstractDispatcher() = default;
80 virtual ~AbstractDispatcher() { }
81
82 virtual void Dispatch(Header* header) = 0;
Jeff Hao3ab96b42016-09-09 18:35:01 -070083 virtual void Dispatch(const StringData* string_data) = 0;
David Sehr7629f602016-08-07 16:01:51 -070084 virtual void Dispatch(const StringId* string_id) = 0;
85 virtual void Dispatch(const TypeId* type_id) = 0;
86 virtual void Dispatch(const ProtoId* proto_id) = 0;
87 virtual void Dispatch(const FieldId* field_id) = 0;
88 virtual void Dispatch(const MethodId* method_id) = 0;
Jeff Hao5daee902017-04-27 18:00:38 -070089 virtual void Dispatch(const CallSiteId* call_site_id) = 0;
90 virtual void Dispatch(const MethodHandleItem* method_handle_item) = 0;
David Sehr7629f602016-08-07 16:01:51 -070091 virtual void Dispatch(ClassData* class_data) = 0;
92 virtual void Dispatch(ClassDef* class_def) = 0;
93 virtual void Dispatch(FieldItem* field_item) = 0;
94 virtual void Dispatch(MethodItem* method_item) = 0;
Jeff Hao3ab96b42016-09-09 18:35:01 -070095 virtual void Dispatch(EncodedArrayItem* array_item) = 0;
David Sehr7629f602016-08-07 16:01:51 -070096 virtual void Dispatch(CodeItem* code_item) = 0;
97 virtual void Dispatch(TryItem* try_item) = 0;
98 virtual void Dispatch(DebugInfoItem* debug_info_item) = 0;
Jeff Hao3ab96b42016-09-09 18:35:01 -070099 virtual void Dispatch(AnnotationItem* annotation_item) = 0;
David Sehr7629f602016-08-07 16:01:51 -0700100 virtual void Dispatch(AnnotationSetItem* annotation_set_item) = 0;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700101 virtual void Dispatch(AnnotationSetRefList* annotation_set_ref_list) = 0;
David Sehr7629f602016-08-07 16:01:51 -0700102 virtual void Dispatch(AnnotationsDirectoryItem* annotations_directory_item) = 0;
103 virtual void Dispatch(MapList* map_list) = 0;
104 virtual void Dispatch(MapItem* map_item) = 0;
105
106 private:
107 DISALLOW_COPY_AND_ASSIGN(AbstractDispatcher);
108};
109
110// Collections become owners of the objects added by moving them into unique pointers.
Jeff Haoea7c6292016-11-14 18:10:16 -0800111template<class T> class CollectionBase {
David Sehr7629f602016-08-07 16:01:51 -0700112 public:
Jeff Haoea7c6292016-11-14 18:10:16 -0800113 CollectionBase() = default;
114
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800115 uint32_t GetOffset() const {
116 return offset_;
117 }
118 void SetOffset(uint32_t new_offset) {
119 offset_ = new_offset;
120 }
Jeff Haoea7c6292016-11-14 18:10:16 -0800121
122 private:
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800123 // Start out unassigned.
124 uint32_t offset_ = 0u;
Jeff Haoea7c6292016-11-14 18:10:16 -0800125
126 DISALLOW_COPY_AND_ASSIGN(CollectionBase);
127};
128
129template<class T> class CollectionVector : public CollectionBase<T> {
130 public:
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800131 using Vector = std::vector<std::unique_ptr<T>>;
Jeff Haoea7c6292016-11-14 18:10:16 -0800132 CollectionVector() = default;
133
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800134 uint32_t Size() const { return collection_.size(); }
135 Vector& Collection() { return collection_; }
Mathieu Chartier8892c6b2018-01-09 15:10:17 -0800136 const Vector& Collection() const { return collection_; }
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800137
138 protected:
139 Vector collection_;
140
141 void AddItem(T* object) {
Jeff Hao3ab96b42016-09-09 18:35:01 -0700142 collection_.push_back(std::unique_ptr<T>(object));
David Sehr7629f602016-08-07 16:01:51 -0700143 }
David Sehr7629f602016-08-07 16:01:51 -0700144
145 private:
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800146 friend class Collections;
Jeff Haoea7c6292016-11-14 18:10:16 -0800147 DISALLOW_COPY_AND_ASSIGN(CollectionVector);
148};
149
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800150template<class T> class IndexedCollectionVector : public CollectionVector<T> {
151 public:
152 using Vector = std::vector<std::unique_ptr<T>>;
153 IndexedCollectionVector() = default;
154
155 private:
156 void AddIndexedItem(T* object, uint32_t index) {
157 object->SetIndex(index);
158 CollectionVector<T>::collection_.push_back(std::unique_ptr<T>(object));
159 }
160
161 friend class Collections;
162 DISALLOW_COPY_AND_ASSIGN(IndexedCollectionVector);
163};
164
Jeff Haoea7c6292016-11-14 18:10:16 -0800165template<class T> class CollectionMap : public CollectionBase<T> {
166 public:
167 CollectionMap() = default;
168
Mathieu Chartiera2973d72017-02-14 17:12:20 -0800169 // Returns the existing item if it is already inserted, null otherwise.
170 T* GetExistingObject(uint32_t offset) {
171 auto it = collection_.find(offset);
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800172 return it != collection_.end() ? it->second : nullptr;
Mathieu Chartiera2973d72017-02-14 17:12:20 -0800173 }
174
Jeff Haoea7c6292016-11-14 18:10:16 -0800175 uint32_t Size() const { return collection_.size(); }
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800176 std::map<uint32_t, T*>& Collection() { return collection_; }
177
178 // Sort the vector by copying pointers over.
179 void SortVectorByMapOrder(CollectionVector<T>& vector) {
180 auto it = collection_.begin();
181 CHECK_EQ(vector.Size(), Size());
182 for (size_t i = 0; i < Size(); ++i) {
183 // There are times when the array will temporarily contain the same pointer twice, doing the
184 // release here sure there is no double free errors.
185 vector.Collection()[i].release();
186 vector.Collection()[i].reset(it->second);
187 ++it;
188 }
189 }
Jeff Haoea7c6292016-11-14 18:10:16 -0800190
191 private:
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800192 std::map<uint32_t, T*> collection_;
Jeff Haoea7c6292016-11-14 18:10:16 -0800193
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800194 void AddItem(T* object, uint32_t offset) {
195 auto it = collection_.emplace(offset, object);
196 CHECK(it.second) << "CollectionMap already has an object with offset " << offset << " "
197 << " and address " << it.first->second;
198 }
199
200 friend class Collections;
Jeff Haoea7c6292016-11-14 18:10:16 -0800201 DISALLOW_COPY_AND_ASSIGN(CollectionMap);
David Sehr7629f602016-08-07 16:01:51 -0700202};
203
Jeff Hao3ab96b42016-09-09 18:35:01 -0700204class Collections {
205 public:
206 Collections() = default;
207
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800208 CollectionVector<StringId>::Vector& StringIds() { return string_ids_.Collection(); }
209 CollectionVector<TypeId>::Vector& TypeIds() { return type_ids_.Collection(); }
210 CollectionVector<ProtoId>::Vector& ProtoIds() { return proto_ids_.Collection(); }
211 CollectionVector<FieldId>::Vector& FieldIds() { return field_ids_.Collection(); }
212 CollectionVector<MethodId>::Vector& MethodIds() { return method_ids_.Collection(); }
213 CollectionVector<ClassDef>::Vector& ClassDefs() { return class_defs_.Collection(); }
214 CollectionVector<CallSiteId>::Vector& CallSiteIds() { return call_site_ids_.Collection(); }
215 CollectionVector<MethodHandleItem>::Vector& MethodHandleItems()
Jeff Hao5daee902017-04-27 18:00:38 -0700216 { return method_handle_items_.Collection(); }
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800217 CollectionVector<StringData>::Vector& StringDatas() { return string_datas_.Collection(); }
218 CollectionVector<TypeList>::Vector& TypeLists() { return type_lists_.Collection(); }
219 CollectionVector<EncodedArrayItem>::Vector& EncodedArrayItems()
Jeff Hao3ab96b42016-09-09 18:35:01 -0700220 { return encoded_array_items_.Collection(); }
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800221 CollectionVector<AnnotationItem>::Vector& AnnotationItems()
Jeff Haoa8621002016-10-04 18:13:44 +0000222 { return annotation_items_.Collection(); }
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800223 CollectionVector<AnnotationSetItem>::Vector& AnnotationSetItems()
Jeff Haoa8621002016-10-04 18:13:44 +0000224 { return annotation_set_items_.Collection(); }
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800225 CollectionVector<AnnotationSetRefList>::Vector& AnnotationSetRefLists()
Jeff Haoa8621002016-10-04 18:13:44 +0000226 { return annotation_set_ref_lists_.Collection(); }
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800227 CollectionVector<AnnotationsDirectoryItem>::Vector& AnnotationsDirectoryItems()
Jeff Haoa8621002016-10-04 18:13:44 +0000228 { return annotations_directory_items_.Collection(); }
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800229 CollectionVector<DebugInfoItem>::Vector& DebugInfoItems()
Jeff Haoa8621002016-10-04 18:13:44 +0000230 { return debug_info_items_.Collection(); }
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800231 CollectionVector<CodeItem>::Vector& CodeItems() { return code_items_.Collection(); }
232 CollectionVector<ClassData>::Vector& ClassDatas() { return class_datas_.Collection(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700233
Mathieu Chartier8892c6b2018-01-09 15:10:17 -0800234 const CollectionVector<ClassDef>::Vector& ClassDefs() const { return class_defs_.Collection(); }
235
Jeff Hao3ab96b42016-09-09 18:35:01 -0700236 void CreateStringId(const DexFile& dex_file, uint32_t i);
237 void CreateTypeId(const DexFile& dex_file, uint32_t i);
238 void CreateProtoId(const DexFile& dex_file, uint32_t i);
239 void CreateFieldId(const DexFile& dex_file, uint32_t i);
240 void CreateMethodId(const DexFile& dex_file, uint32_t i);
241 void CreateClassDef(const DexFile& dex_file, uint32_t i);
Jeff Hao5daee902017-04-27 18:00:38 -0700242 void CreateCallSiteId(const DexFile& dex_file, uint32_t i);
243 void CreateMethodHandleItem(const DexFile& dex_file, uint32_t i);
244
245 void CreateCallSitesAndMethodHandles(const DexFile& dex_file);
Jeff Hao3ab96b42016-09-09 18:35:01 -0700246
Jeff Haoa8621002016-10-04 18:13:44 +0000247 TypeList* CreateTypeList(const DexFile::TypeList* type_list, uint32_t offset);
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800248 EncodedArrayItem* CreateEncodedArrayItem(const DexFile& dex_file,
249 const uint8_t* static_data,
250 uint32_t offset);
Mathieu Chartier24066ec2017-10-21 16:01:08 -0700251 AnnotationItem* CreateAnnotationItem(const DexFile& dex_file,
252 const DexFile::AnnotationItem* annotation);
Jeff Hao3ab96b42016-09-09 18:35:01 -0700253 AnnotationSetItem* CreateAnnotationSetItem(const DexFile& dex_file,
Jeff Haobe9b44b2017-02-16 13:34:38 -0800254 const DexFile::AnnotationSetItem* disk_annotations_item, uint32_t offset);
Jeff Hao3ab96b42016-09-09 18:35:01 -0700255 AnnotationsDirectoryItem* CreateAnnotationsDirectoryItem(const DexFile& dex_file,
256 const DexFile::AnnotationsDirectoryItem* disk_annotations_item, uint32_t offset);
Mathieu Chartier8892c6b2018-01-09 15:10:17 -0800257 CodeItem* CreateCodeItem(const DexFile& dex_file,
258 const DexFile::CodeItem& disk_code_item,
259 uint32_t offset,
260 uint32_t dex_method_index);
Jeff Hao3ab96b42016-09-09 18:35:01 -0700261 ClassData* CreateClassData(const DexFile& dex_file, const uint8_t* encoded_data, uint32_t offset);
Mathieu Chartier24066ec2017-10-21 16:01:08 -0700262 void AddAnnotationsFromMapListSection(const DexFile& dex_file,
263 uint32_t start_offset,
264 uint32_t count);
Jeff Hao3ab96b42016-09-09 18:35:01 -0700265
Jeff Hao9804e9e2017-06-15 14:04:51 -0700266 StringId* GetStringId(uint32_t index) {
267 CHECK_LT(index, StringIdsSize());
268 return StringIds()[index].get();
269 }
270 TypeId* GetTypeId(uint32_t index) {
271 CHECK_LT(index, TypeIdsSize());
272 return TypeIds()[index].get();
273 }
274 ProtoId* GetProtoId(uint32_t index) {
275 CHECK_LT(index, ProtoIdsSize());
276 return ProtoIds()[index].get();
277 }
278 FieldId* GetFieldId(uint32_t index) {
279 CHECK_LT(index, FieldIdsSize());
280 return FieldIds()[index].get();
281 }
282 MethodId* GetMethodId(uint32_t index) {
283 CHECK_LT(index, MethodIdsSize());
284 return MethodIds()[index].get();
285 }
286 ClassDef* GetClassDef(uint32_t index) {
287 CHECK_LT(index, ClassDefsSize());
288 return ClassDefs()[index].get();
289 }
290 CallSiteId* GetCallSiteId(uint32_t index) {
291 CHECK_LT(index, CallSiteIdsSize());
292 return CallSiteIds()[index].get();
293 }
294 MethodHandleItem* GetMethodHandle(uint32_t index) {
295 CHECK_LT(index, MethodHandleItemsSize());
296 return MethodHandleItems()[index].get();
297 }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700298
299 StringId* GetStringIdOrNullPtr(uint32_t index) {
Andreas Gampee2abbc62017-09-15 11:59:26 -0700300 return index == dex::kDexNoIndex ? nullptr : GetStringId(index);
Jeff Hao3ab96b42016-09-09 18:35:01 -0700301 }
302 TypeId* GetTypeIdOrNullPtr(uint16_t index) {
303 return index == DexFile::kDexNoIndex16 ? nullptr : GetTypeId(index);
304 }
305
306 uint32_t StringIdsOffset() const { return string_ids_.GetOffset(); }
307 uint32_t TypeIdsOffset() const { return type_ids_.GetOffset(); }
308 uint32_t ProtoIdsOffset() const { return proto_ids_.GetOffset(); }
309 uint32_t FieldIdsOffset() const { return field_ids_.GetOffset(); }
310 uint32_t MethodIdsOffset() const { return method_ids_.GetOffset(); }
311 uint32_t ClassDefsOffset() const { return class_defs_.GetOffset(); }
Jeff Hao5daee902017-04-27 18:00:38 -0700312 uint32_t CallSiteIdsOffset() const { return call_site_ids_.GetOffset(); }
313 uint32_t MethodHandleItemsOffset() const { return method_handle_items_.GetOffset(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700314 uint32_t StringDatasOffset() const { return string_datas_.GetOffset(); }
315 uint32_t TypeListsOffset() const { return type_lists_.GetOffset(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000316 uint32_t EncodedArrayItemsOffset() const { return encoded_array_items_.GetOffset(); }
317 uint32_t AnnotationItemsOffset() const { return annotation_items_.GetOffset(); }
318 uint32_t AnnotationSetItemsOffset() const { return annotation_set_items_.GetOffset(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700319 uint32_t AnnotationSetRefListsOffset() const { return annotation_set_ref_lists_.GetOffset(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000320 uint32_t AnnotationsDirectoryItemsOffset() const
321 { return annotations_directory_items_.GetOffset(); }
322 uint32_t DebugInfoItemsOffset() const { return debug_info_items_.GetOffset(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700323 uint32_t CodeItemsOffset() const { return code_items_.GetOffset(); }
324 uint32_t ClassDatasOffset() const { return class_datas_.GetOffset(); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800325 uint32_t MapListOffset() const { return map_list_offset_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700326
327 void SetStringIdsOffset(uint32_t new_offset) { string_ids_.SetOffset(new_offset); }
328 void SetTypeIdsOffset(uint32_t new_offset) { type_ids_.SetOffset(new_offset); }
329 void SetProtoIdsOffset(uint32_t new_offset) { proto_ids_.SetOffset(new_offset); }
330 void SetFieldIdsOffset(uint32_t new_offset) { field_ids_.SetOffset(new_offset); }
331 void SetMethodIdsOffset(uint32_t new_offset) { method_ids_.SetOffset(new_offset); }
332 void SetClassDefsOffset(uint32_t new_offset) { class_defs_.SetOffset(new_offset); }
Jeff Hao5daee902017-04-27 18:00:38 -0700333 void SetCallSiteIdsOffset(uint32_t new_offset) { call_site_ids_.SetOffset(new_offset); }
334 void SetMethodHandleItemsOffset(uint32_t new_offset)
335 { method_handle_items_.SetOffset(new_offset); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700336 void SetStringDatasOffset(uint32_t new_offset) { string_datas_.SetOffset(new_offset); }
337 void SetTypeListsOffset(uint32_t new_offset) { type_lists_.SetOffset(new_offset); }
Jeff Haoa8621002016-10-04 18:13:44 +0000338 void SetEncodedArrayItemsOffset(uint32_t new_offset)
339 { encoded_array_items_.SetOffset(new_offset); }
340 void SetAnnotationItemsOffset(uint32_t new_offset) { annotation_items_.SetOffset(new_offset); }
341 void SetAnnotationSetItemsOffset(uint32_t new_offset)
342 { annotation_set_items_.SetOffset(new_offset); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700343 void SetAnnotationSetRefListsOffset(uint32_t new_offset)
344 { annotation_set_ref_lists_.SetOffset(new_offset); }
Jeff Haoa8621002016-10-04 18:13:44 +0000345 void SetAnnotationsDirectoryItemsOffset(uint32_t new_offset)
Jeff Hao3ab96b42016-09-09 18:35:01 -0700346 { annotations_directory_items_.SetOffset(new_offset); }
Jeff Haoa8621002016-10-04 18:13:44 +0000347 void SetDebugInfoItemsOffset(uint32_t new_offset) { debug_info_items_.SetOffset(new_offset); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700348 void SetCodeItemsOffset(uint32_t new_offset) { code_items_.SetOffset(new_offset); }
349 void SetClassDatasOffset(uint32_t new_offset) { class_datas_.SetOffset(new_offset); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800350 void SetMapListOffset(uint32_t new_offset) { map_list_offset_ = new_offset; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700351
352 uint32_t StringIdsSize() const { return string_ids_.Size(); }
353 uint32_t TypeIdsSize() const { return type_ids_.Size(); }
354 uint32_t ProtoIdsSize() const { return proto_ids_.Size(); }
355 uint32_t FieldIdsSize() const { return field_ids_.Size(); }
356 uint32_t MethodIdsSize() const { return method_ids_.Size(); }
357 uint32_t ClassDefsSize() const { return class_defs_.Size(); }
Jeff Hao5daee902017-04-27 18:00:38 -0700358 uint32_t CallSiteIdsSize() const { return call_site_ids_.Size(); }
359 uint32_t MethodHandleItemsSize() const { return method_handle_items_.Size(); }
David Sehrcdcfde72016-09-26 07:44:04 -0700360 uint32_t StringDatasSize() const { return string_datas_.Size(); }
361 uint32_t TypeListsSize() const { return type_lists_.Size(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000362 uint32_t EncodedArrayItemsSize() const { return encoded_array_items_.Size(); }
363 uint32_t AnnotationItemsSize() const { return annotation_items_.Size(); }
364 uint32_t AnnotationSetItemsSize() const { return annotation_set_items_.Size(); }
David Sehrcdcfde72016-09-26 07:44:04 -0700365 uint32_t AnnotationSetRefListsSize() const { return annotation_set_ref_lists_.Size(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000366 uint32_t AnnotationsDirectoryItemsSize() const { return annotations_directory_items_.Size(); }
367 uint32_t DebugInfoItemsSize() const { return debug_info_items_.Size(); }
David Sehrcdcfde72016-09-26 07:44:04 -0700368 uint32_t CodeItemsSize() const { return code_items_.Size(); }
369 uint32_t ClassDatasSize() const { return class_datas_.Size(); }
370
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800371 // Sort the vectors buy map order (same order that was used in the input file).
372 void SortVectorsByMapOrder();
373
374 template <typename Type>
375 void AddItem(CollectionMap<Type>& map,
376 CollectionVector<Type>& vector,
377 Type* item,
378 uint32_t offset) {
379 DCHECK(!map.GetExistingObject(offset));
380 DCHECK(!item->OffsetAssigned());
381 if (eagerly_assign_offsets_) {
382 item->SetOffset(offset);
383 }
384 map.AddItem(item, offset);
385 vector.AddItem(item);
386 }
387
388 template <typename Type>
389 void AddIndexedItem(IndexedCollectionVector<Type>& vector,
390 Type* item,
391 uint32_t offset,
392 uint32_t index) {
393 DCHECK(!item->OffsetAssigned());
394 if (eagerly_assign_offsets_) {
395 item->SetOffset(offset);
396 }
397 vector.AddIndexedItem(item, index);
398 }
399
400 void SetEagerlyAssignOffsets(bool eagerly_assign_offsets) {
401 eagerly_assign_offsets_ = eagerly_assign_offsets;
402 }
403
Mathieu Chartier2f36d2f2017-11-20 15:45:25 -0800404 void SetLinkData(std::vector<uint8_t>&& link_data) {
405 link_data_ = std::move(link_data);
406 }
407
408 const std::vector<uint8_t>& LinkData() const {
409 return link_data_;
410 }
411
Jeff Hao3ab96b42016-09-09 18:35:01 -0700412 private:
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800413 EncodedValue* ReadEncodedValue(const DexFile& dex_file, const uint8_t** data);
414 EncodedValue* ReadEncodedValue(const DexFile& dex_file,
415 const uint8_t** data,
416 uint8_t type,
417 uint8_t length);
418 void ReadEncodedValue(const DexFile& dex_file,
419 const uint8_t** data,
420 uint8_t type,
421 uint8_t length,
422 EncodedValue* item);
Jeff Hao3ab96b42016-09-09 18:35:01 -0700423
424 ParameterAnnotation* GenerateParameterAnnotation(const DexFile& dex_file, MethodId* method_id,
425 const DexFile::AnnotationSetRefList* annotation_set_ref_list, uint32_t offset);
426 MethodItem* GenerateMethodItem(const DexFile& dex_file, ClassDataItemIterator& cdii);
427
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800428 // Collection vectors own the IR data.
429 IndexedCollectionVector<StringId> string_ids_;
430 IndexedCollectionVector<TypeId> type_ids_;
431 IndexedCollectionVector<ProtoId> proto_ids_;
432 IndexedCollectionVector<FieldId> field_ids_;
433 IndexedCollectionVector<MethodId> method_ids_;
434 IndexedCollectionVector<CallSiteId> call_site_ids_;
435 IndexedCollectionVector<MethodHandleItem> method_handle_items_;
436 IndexedCollectionVector<StringData> string_datas_;
437 IndexedCollectionVector<TypeList> type_lists_;
438 IndexedCollectionVector<EncodedArrayItem> encoded_array_items_;
439 IndexedCollectionVector<AnnotationItem> annotation_items_;
440 IndexedCollectionVector<AnnotationSetItem> annotation_set_items_;
441 IndexedCollectionVector<AnnotationSetRefList> annotation_set_ref_lists_;
442 IndexedCollectionVector<AnnotationsDirectoryItem> annotations_directory_items_;
443 IndexedCollectionVector<ClassDef> class_defs_;
444 // The order of the vectors controls the layout of the output file by index order, to change the
445 // layout just sort the vector. Note that you may only change the order of the non indexed vectors
446 // below. Indexed vectors are accessed by indices in other places, changing the sorting order will
447 // invalidate the existing indices and is not currently supported.
448 CollectionVector<DebugInfoItem> debug_info_items_;
449 CollectionVector<CodeItem> code_items_;
450 CollectionVector<ClassData> class_datas_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700451
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800452 // Note that the maps do not have ownership, the vectors do.
453 // TODO: These maps should only be required for building the IR and should be put in a separate
454 // IR builder class.
455 CollectionMap<StringData> string_datas_map_;
456 CollectionMap<TypeList> type_lists_map_;
457 CollectionMap<EncodedArrayItem> encoded_array_items_map_;
458 CollectionMap<AnnotationItem> annotation_items_map_;
459 CollectionMap<AnnotationSetItem> annotation_set_items_map_;
460 CollectionMap<AnnotationSetRefList> annotation_set_ref_lists_map_;
461 CollectionMap<AnnotationsDirectoryItem> annotations_directory_items_map_;
462 CollectionMap<DebugInfoItem> debug_info_items_map_;
463 CollectionMap<CodeItem> code_items_map_;
464 CollectionMap<ClassData> class_datas_map_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700465
Jeff Haoea7c6292016-11-14 18:10:16 -0800466 uint32_t map_list_offset_ = 0;
Jeff Haoa8621002016-10-04 18:13:44 +0000467
Mathieu Chartier2f36d2f2017-11-20 15:45:25 -0800468 // Link data.
469 std::vector<uint8_t> link_data_;
470
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800471 // If we eagerly assign offsets during IR building or later after layout. Must be false if
472 // changing the layout is enabled.
473 bool eagerly_assign_offsets_;
474
Jeff Hao3ab96b42016-09-09 18:35:01 -0700475 DISALLOW_COPY_AND_ASSIGN(Collections);
476};
477
David Sehr7629f602016-08-07 16:01:51 -0700478class Item {
479 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700480 Item() { }
David Sehr7629f602016-08-07 16:01:51 -0700481 virtual ~Item() { }
David Sehr853a8e12016-09-01 13:03:50 -0700482
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800483 // Return the assigned offset.
484 uint32_t GetOffset() const {
485 CHECK(OffsetAssigned());
486 return offset_;
487 }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700488 uint32_t GetSize() const { return size_; }
David Sehr7629f602016-08-07 16:01:51 -0700489 void SetOffset(uint32_t offset) { offset_ = offset; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700490 void SetSize(uint32_t size) { size_ = size; }
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800491 bool OffsetAssigned() const {
492 return offset_ != kOffsetUnassigned;
493 }
David Sehr853a8e12016-09-01 13:03:50 -0700494
David Sehr7629f602016-08-07 16:01:51 -0700495 protected:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700496 Item(uint32_t offset, uint32_t size) : offset_(offset), size_(size) { }
497
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800498 // 0 is the dex file header and shouldn't be a valid offset for any part of the dex file.
499 static constexpr uint32_t kOffsetUnassigned = 0u;
500
501 // Start out unassigned.
502 uint32_t offset_ = kOffsetUnassigned;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700503 uint32_t size_ = 0;
504};
505
506class IndexedItem : public Item {
507 public:
508 IndexedItem() { }
509 virtual ~IndexedItem() { }
510
511 uint32_t GetIndex() const { return index_; }
512 void SetIndex(uint32_t index) { index_ = index; }
513
514 protected:
515 IndexedItem(uint32_t offset, uint32_t size, uint32_t index)
516 : Item(offset, size), index_(index) { }
517
518 uint32_t index_ = 0;
David Sehr7629f602016-08-07 16:01:51 -0700519};
520
521class Header : public Item {
522 public:
David Sehr853a8e12016-09-01 13:03:50 -0700523 Header(const uint8_t* magic,
524 uint32_t checksum,
525 const uint8_t* signature,
526 uint32_t endian_tag,
527 uint32_t file_size,
528 uint32_t header_size,
529 uint32_t link_size,
530 uint32_t link_offset,
531 uint32_t data_size,
Mathieu Chartierf6e31472017-12-28 13:32:08 -0800532 uint32_t data_offset,
533 bool support_default_methods)
Jeff Hao3ab96b42016-09-09 18:35:01 -0700534 : Item(0, kHeaderItemSize),
535 checksum_(checksum),
David Sehr853a8e12016-09-01 13:03:50 -0700536 endian_tag_(endian_tag),
537 file_size_(file_size),
538 header_size_(header_size),
539 link_size_(link_size),
540 link_offset_(link_offset),
541 data_size_(data_size),
Mathieu Chartierf6e31472017-12-28 13:32:08 -0800542 data_offset_(data_offset),
543 support_default_methods_(support_default_methods) {
David Sehr853a8e12016-09-01 13:03:50 -0700544 memcpy(magic_, magic, sizeof(magic_));
545 memcpy(signature_, signature, sizeof(signature_));
546 }
David Sehr7629f602016-08-07 16:01:51 -0700547 ~Header() OVERRIDE { }
548
Jeff Hao3ab96b42016-09-09 18:35:01 -0700549 static size_t ItemSize() { return kHeaderItemSize; }
550
David Sehr7629f602016-08-07 16:01:51 -0700551 const uint8_t* Magic() const { return magic_; }
552 uint32_t Checksum() const { return checksum_; }
553 const uint8_t* Signature() const { return signature_; }
554 uint32_t EndianTag() const { return endian_tag_; }
555 uint32_t FileSize() const { return file_size_; }
556 uint32_t HeaderSize() const { return header_size_; }
557 uint32_t LinkSize() const { return link_size_; }
558 uint32_t LinkOffset() const { return link_offset_; }
559 uint32_t DataSize() const { return data_size_; }
560 uint32_t DataOffset() const { return data_offset_; }
561
562 void SetChecksum(uint32_t new_checksum) { checksum_ = new_checksum; }
563 void SetSignature(const uint8_t* new_signature) {
564 memcpy(signature_, new_signature, sizeof(signature_));
565 }
566 void SetFileSize(uint32_t new_file_size) { file_size_ = new_file_size; }
567 void SetHeaderSize(uint32_t new_header_size) { header_size_ = new_header_size; }
568 void SetLinkSize(uint32_t new_link_size) { link_size_ = new_link_size; }
569 void SetLinkOffset(uint32_t new_link_offset) { link_offset_ = new_link_offset; }
570 void SetDataSize(uint32_t new_data_size) { data_size_ = new_data_size; }
571 void SetDataOffset(uint32_t new_data_offset) { data_offset_ = new_data_offset; }
572
Jeff Hao3ab96b42016-09-09 18:35:01 -0700573 Collections& GetCollections() { return collections_; }
Jeff Haoc3acfc52016-08-29 14:18:26 -0700574
David Sehr7629f602016-08-07 16:01:51 -0700575 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
576
Mathieu Chartierf6e31472017-12-28 13:32:08 -0800577 bool SupportDefaultMethods() const {
578 return support_default_methods_;
579 }
580
David Sehr7629f602016-08-07 16:01:51 -0700581 private:
David Sehr7629f602016-08-07 16:01:51 -0700582 uint8_t magic_[8];
583 uint32_t checksum_;
584 uint8_t signature_[DexFile::kSha1DigestSize];
585 uint32_t endian_tag_;
586 uint32_t file_size_;
587 uint32_t header_size_;
588 uint32_t link_size_;
589 uint32_t link_offset_;
590 uint32_t data_size_;
591 uint32_t data_offset_;
Mathieu Chartierf6e31472017-12-28 13:32:08 -0800592 const bool support_default_methods_;
David Sehr7629f602016-08-07 16:01:51 -0700593
Jeff Hao3ab96b42016-09-09 18:35:01 -0700594 Collections collections_;
595
David Sehr7629f602016-08-07 16:01:51 -0700596 DISALLOW_COPY_AND_ASSIGN(Header);
597};
598
Jeff Hao3ab96b42016-09-09 18:35:01 -0700599class StringData : public Item {
David Sehr7629f602016-08-07 16:01:51 -0700600 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700601 explicit StringData(const char* data) : data_(strdup(data)) {
Jeff Haoa8621002016-10-04 18:13:44 +0000602 size_ = UnsignedLeb128Size(CountModifiedUtf8Chars(data)) + strlen(data);
Jeff Hao3ab96b42016-09-09 18:35:01 -0700603 }
David Sehr7629f602016-08-07 16:01:51 -0700604
605 const char* Data() const { return data_.get(); }
606
607 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
608
609 private:
Jeff Haoa8621002016-10-04 18:13:44 +0000610 UniqueCPtr<const char> data_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700611
612 DISALLOW_COPY_AND_ASSIGN(StringData);
613};
614
615class StringId : public IndexedItem {
616 public:
617 explicit StringId(StringData* string_data) : string_data_(string_data) {
618 size_ = kStringIdItemSize;
619 }
620 ~StringId() OVERRIDE { }
621
622 static size_t ItemSize() { return kStringIdItemSize; }
623
624 const char* Data() const { return string_data_->Data(); }
625 StringData* DataItem() const { return string_data_; }
626
627 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
628
629 private:
630 StringData* string_data_;
631
David Sehr7629f602016-08-07 16:01:51 -0700632 DISALLOW_COPY_AND_ASSIGN(StringId);
633};
634
Jeff Hao3ab96b42016-09-09 18:35:01 -0700635class TypeId : public IndexedItem {
David Sehr7629f602016-08-07 16:01:51 -0700636 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700637 explicit TypeId(StringId* string_id) : string_id_(string_id) { size_ = kTypeIdItemSize; }
David Sehr7629f602016-08-07 16:01:51 -0700638 ~TypeId() OVERRIDE { }
639
Jeff Hao3ab96b42016-09-09 18:35:01 -0700640 static size_t ItemSize() { return kTypeIdItemSize; }
641
David Sehr7629f602016-08-07 16:01:51 -0700642 StringId* GetStringId() const { return string_id_; }
643
644 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
645
646 private:
647 StringId* string_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700648
David Sehr7629f602016-08-07 16:01:51 -0700649 DISALLOW_COPY_AND_ASSIGN(TypeId);
650};
651
David Sehr853a8e12016-09-01 13:03:50 -0700652using TypeIdVector = std::vector<const TypeId*>;
653
Jeff Hao3ab96b42016-09-09 18:35:01 -0700654class TypeList : public Item {
David Sehr7629f602016-08-07 16:01:51 -0700655 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700656 explicit TypeList(TypeIdVector* type_list) : type_list_(type_list) {
657 size_ = sizeof(uint32_t) + (type_list->size() * sizeof(uint16_t));
658 }
659 ~TypeList() OVERRIDE { }
660
661 const TypeIdVector* GetTypeList() const { return type_list_.get(); }
662
663 private:
664 std::unique_ptr<TypeIdVector> type_list_;
665
666 DISALLOW_COPY_AND_ASSIGN(TypeList);
667};
668
669class ProtoId : public IndexedItem {
670 public:
671 ProtoId(const StringId* shorty, const TypeId* return_type, TypeList* parameters)
672 : shorty_(shorty), return_type_(return_type), parameters_(parameters)
673 { size_ = kProtoIdItemSize; }
David Sehr7629f602016-08-07 16:01:51 -0700674 ~ProtoId() OVERRIDE { }
675
Jeff Hao3ab96b42016-09-09 18:35:01 -0700676 static size_t ItemSize() { return kProtoIdItemSize; }
677
David Sehr7629f602016-08-07 16:01:51 -0700678 const StringId* Shorty() const { return shorty_; }
679 const TypeId* ReturnType() const { return return_type_; }
Jeff Haoa8621002016-10-04 18:13:44 +0000680 const TypeList* Parameters() const { return parameters_; }
David Sehr7629f602016-08-07 16:01:51 -0700681
682 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
683
684 private:
685 const StringId* shorty_;
686 const TypeId* return_type_;
Jeff Haoa8621002016-10-04 18:13:44 +0000687 TypeList* parameters_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -0700688
David Sehr7629f602016-08-07 16:01:51 -0700689 DISALLOW_COPY_AND_ASSIGN(ProtoId);
690};
691
Jeff Hao3ab96b42016-09-09 18:35:01 -0700692class FieldId : public IndexedItem {
David Sehr7629f602016-08-07 16:01:51 -0700693 public:
David Sehr853a8e12016-09-01 13:03:50 -0700694 FieldId(const TypeId* klass, const TypeId* type, const StringId* name)
Jeff Hao3ab96b42016-09-09 18:35:01 -0700695 : class_(klass), type_(type), name_(name) { size_ = kFieldIdItemSize; }
David Sehr7629f602016-08-07 16:01:51 -0700696 ~FieldId() OVERRIDE { }
697
Jeff Hao3ab96b42016-09-09 18:35:01 -0700698 static size_t ItemSize() { return kFieldIdItemSize; }
699
David Sehr7629f602016-08-07 16:01:51 -0700700 const TypeId* Class() const { return class_; }
701 const TypeId* Type() const { return type_; }
702 const StringId* Name() const { return name_; }
703
704 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
705
706 private:
707 const TypeId* class_;
708 const TypeId* type_;
709 const StringId* name_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700710
David Sehr7629f602016-08-07 16:01:51 -0700711 DISALLOW_COPY_AND_ASSIGN(FieldId);
712};
713
Jeff Hao3ab96b42016-09-09 18:35:01 -0700714class MethodId : public IndexedItem {
David Sehr7629f602016-08-07 16:01:51 -0700715 public:
David Sehr853a8e12016-09-01 13:03:50 -0700716 MethodId(const TypeId* klass, const ProtoId* proto, const StringId* name)
Jeff Hao3ab96b42016-09-09 18:35:01 -0700717 : class_(klass), proto_(proto), name_(name) { size_ = kMethodIdItemSize; }
David Sehr7629f602016-08-07 16:01:51 -0700718 ~MethodId() OVERRIDE { }
719
Jeff Hao3ab96b42016-09-09 18:35:01 -0700720 static size_t ItemSize() { return kMethodIdItemSize; }
721
David Sehr7629f602016-08-07 16:01:51 -0700722 const TypeId* Class() const { return class_; }
723 const ProtoId* Proto() const { return proto_; }
724 const StringId* Name() const { return name_; }
725
726 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
727
728 private:
729 const TypeId* class_;
730 const ProtoId* proto_;
731 const StringId* name_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700732
David Sehr7629f602016-08-07 16:01:51 -0700733 DISALLOW_COPY_AND_ASSIGN(MethodId);
734};
735
736class FieldItem : public Item {
737 public:
David Sehr853a8e12016-09-01 13:03:50 -0700738 FieldItem(uint32_t access_flags, const FieldId* field_id)
739 : access_flags_(access_flags), field_id_(field_id) { }
David Sehr7629f602016-08-07 16:01:51 -0700740 ~FieldItem() OVERRIDE { }
741
742 uint32_t GetAccessFlags() const { return access_flags_; }
743 const FieldId* GetFieldId() const { return field_id_; }
744
745 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
746
747 private:
748 uint32_t access_flags_;
749 const FieldId* field_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700750
David Sehr7629f602016-08-07 16:01:51 -0700751 DISALLOW_COPY_AND_ASSIGN(FieldItem);
752};
753
David Sehr853a8e12016-09-01 13:03:50 -0700754using FieldItemVector = std::vector<std::unique_ptr<FieldItem>>;
755
David Sehr7629f602016-08-07 16:01:51 -0700756class MethodItem : public Item {
757 public:
Jeff Haoea7c6292016-11-14 18:10:16 -0800758 MethodItem(uint32_t access_flags, const MethodId* method_id, CodeItem* code)
David Sehr853a8e12016-09-01 13:03:50 -0700759 : access_flags_(access_flags), method_id_(method_id), code_(code) { }
David Sehr7629f602016-08-07 16:01:51 -0700760 ~MethodItem() OVERRIDE { }
761
762 uint32_t GetAccessFlags() const { return access_flags_; }
763 const MethodId* GetMethodId() const { return method_id_; }
Jeff Haoea7c6292016-11-14 18:10:16 -0800764 CodeItem* GetCodeItem() { return code_; }
David Sehr7629f602016-08-07 16:01:51 -0700765
766 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
767
768 private:
769 uint32_t access_flags_;
770 const MethodId* method_id_;
Jeff Haoea7c6292016-11-14 18:10:16 -0800771 CodeItem* code_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -0700772
David Sehr7629f602016-08-07 16:01:51 -0700773 DISALLOW_COPY_AND_ASSIGN(MethodItem);
774};
775
David Sehr853a8e12016-09-01 13:03:50 -0700776using MethodItemVector = std::vector<std::unique_ptr<MethodItem>>;
777
Jeff Hao3ab96b42016-09-09 18:35:01 -0700778class EncodedValue {
David Sehr7629f602016-08-07 16:01:51 -0700779 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700780 explicit EncodedValue(uint8_t type) : type_(type) { }
David Sehr7629f602016-08-07 16:01:51 -0700781
782 int8_t Type() const { return type_; }
David Sehr7629f602016-08-07 16:01:51 -0700783
Jeff Hao3ab96b42016-09-09 18:35:01 -0700784 void SetBoolean(bool z) { u_.bool_val_ = z; }
785 void SetByte(int8_t b) { u_.byte_val_ = b; }
786 void SetShort(int16_t s) { u_.short_val_ = s; }
787 void SetChar(uint16_t c) { u_.char_val_ = c; }
788 void SetInt(int32_t i) { u_.int_val_ = i; }
789 void SetLong(int64_t l) { u_.long_val_ = l; }
790 void SetFloat(float f) { u_.float_val_ = f; }
791 void SetDouble(double d) { u_.double_val_ = d; }
792 void SetStringId(StringId* string_id) { u_.string_val_ = string_id; }
793 void SetTypeId(TypeId* type_id) { u_.type_val_ = type_id; }
Jeff Hao5daee902017-04-27 18:00:38 -0700794 void SetProtoId(ProtoId* proto_id) { u_.proto_val_ = proto_id; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700795 void SetFieldId(FieldId* field_id) { u_.field_val_ = field_id; }
796 void SetMethodId(MethodId* method_id) { u_.method_val_ = method_id; }
Jeff Hao5daee902017-04-27 18:00:38 -0700797 void SetMethodHandle(MethodHandleItem* method_handle) { u_.method_handle_val_ = method_handle; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700798 void SetEncodedArray(EncodedArrayItem* encoded_array) { encoded_array_.reset(encoded_array); }
799 void SetEncodedAnnotation(EncodedAnnotation* encoded_annotation)
800 { encoded_annotation_.reset(encoded_annotation); }
801
802 bool GetBoolean() const { return u_.bool_val_; }
803 int8_t GetByte() const { return u_.byte_val_; }
804 int16_t GetShort() const { return u_.short_val_; }
805 uint16_t GetChar() const { return u_.char_val_; }
806 int32_t GetInt() const { return u_.int_val_; }
807 int64_t GetLong() const { return u_.long_val_; }
808 float GetFloat() const { return u_.float_val_; }
809 double GetDouble() const { return u_.double_val_; }
810 StringId* GetStringId() const { return u_.string_val_; }
811 TypeId* GetTypeId() const { return u_.type_val_; }
Jeff Hao5daee902017-04-27 18:00:38 -0700812 ProtoId* GetProtoId() const { return u_.proto_val_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700813 FieldId* GetFieldId() const { return u_.field_val_; }
814 MethodId* GetMethodId() const { return u_.method_val_; }
Jeff Hao5daee902017-04-27 18:00:38 -0700815 MethodHandleItem* GetMethodHandle() const { return u_.method_handle_val_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700816 EncodedArrayItem* GetEncodedArray() const { return encoded_array_.get(); }
817 EncodedAnnotation* GetEncodedAnnotation() const { return encoded_annotation_.get(); }
818
819 EncodedAnnotation* ReleaseEncodedAnnotation() { return encoded_annotation_.release(); }
David Sehr7629f602016-08-07 16:01:51 -0700820
821 private:
David Sehr7629f602016-08-07 16:01:51 -0700822 uint8_t type_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700823 union {
824 bool bool_val_;
825 int8_t byte_val_;
826 int16_t short_val_;
827 uint16_t char_val_;
828 int32_t int_val_;
829 int64_t long_val_;
830 float float_val_;
831 double double_val_;
832 StringId* string_val_;
833 TypeId* type_val_;
Jeff Hao5daee902017-04-27 18:00:38 -0700834 ProtoId* proto_val_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700835 FieldId* field_val_;
836 MethodId* method_val_;
Jeff Hao5daee902017-04-27 18:00:38 -0700837 MethodHandleItem* method_handle_val_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700838 } u_;
839 std::unique_ptr<EncodedArrayItem> encoded_array_;
840 std::unique_ptr<EncodedAnnotation> encoded_annotation_;
841
842 DISALLOW_COPY_AND_ASSIGN(EncodedValue);
David Sehr7629f602016-08-07 16:01:51 -0700843};
844
Jeff Hao3ab96b42016-09-09 18:35:01 -0700845using EncodedValueVector = std::vector<std::unique_ptr<EncodedValue>>;
846
847class AnnotationElement {
848 public:
849 AnnotationElement(StringId* name, EncodedValue* value) : name_(name), value_(value) { }
850
851 StringId* GetName() const { return name_; }
852 EncodedValue* GetValue() const { return value_.get(); }
853
854 private:
855 StringId* name_;
856 std::unique_ptr<EncodedValue> value_;
857
858 DISALLOW_COPY_AND_ASSIGN(AnnotationElement);
859};
860
861using AnnotationElementVector = std::vector<std::unique_ptr<AnnotationElement>>;
862
863class EncodedAnnotation {
864 public:
865 EncodedAnnotation(TypeId* type, AnnotationElementVector* elements)
866 : type_(type), elements_(elements) { }
867
868 TypeId* GetType() const { return type_; }
869 AnnotationElementVector* GetAnnotationElements() const { return elements_.get(); }
870
871 private:
872 TypeId* type_;
873 std::unique_ptr<AnnotationElementVector> elements_;
874
875 DISALLOW_COPY_AND_ASSIGN(EncodedAnnotation);
876};
877
878class EncodedArrayItem : public Item {
879 public:
880 explicit EncodedArrayItem(EncodedValueVector* encoded_values)
881 : encoded_values_(encoded_values) { }
882
883 EncodedValueVector* GetEncodedValues() const { return encoded_values_.get(); }
884
885 private:
886 std::unique_ptr<EncodedValueVector> encoded_values_;
887
888 DISALLOW_COPY_AND_ASSIGN(EncodedArrayItem);
889};
David Sehr853a8e12016-09-01 13:03:50 -0700890
David Sehr7629f602016-08-07 16:01:51 -0700891class ClassData : public Item {
892 public:
David Sehr853a8e12016-09-01 13:03:50 -0700893 ClassData(FieldItemVector* static_fields,
894 FieldItemVector* instance_fields,
895 MethodItemVector* direct_methods,
896 MethodItemVector* virtual_methods)
897 : static_fields_(static_fields),
898 instance_fields_(instance_fields),
899 direct_methods_(direct_methods),
900 virtual_methods_(virtual_methods) { }
901
David Sehr7629f602016-08-07 16:01:51 -0700902 ~ClassData() OVERRIDE = default;
David Sehr853a8e12016-09-01 13:03:50 -0700903 FieldItemVector* StaticFields() { return static_fields_.get(); }
904 FieldItemVector* InstanceFields() { return instance_fields_.get(); }
905 MethodItemVector* DirectMethods() { return direct_methods_.get(); }
906 MethodItemVector* VirtualMethods() { return virtual_methods_.get(); }
David Sehr7629f602016-08-07 16:01:51 -0700907
908 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
909
910 private:
David Sehr853a8e12016-09-01 13:03:50 -0700911 std::unique_ptr<FieldItemVector> static_fields_;
912 std::unique_ptr<FieldItemVector> instance_fields_;
913 std::unique_ptr<MethodItemVector> direct_methods_;
914 std::unique_ptr<MethodItemVector> virtual_methods_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700915
David Sehr7629f602016-08-07 16:01:51 -0700916 DISALLOW_COPY_AND_ASSIGN(ClassData);
917};
918
Jeff Hao3ab96b42016-09-09 18:35:01 -0700919class ClassDef : public IndexedItem {
David Sehr7629f602016-08-07 16:01:51 -0700920 public:
David Sehr853a8e12016-09-01 13:03:50 -0700921 ClassDef(const TypeId* class_type,
922 uint32_t access_flags,
923 const TypeId* superclass,
Jeff Hao3ab96b42016-09-09 18:35:01 -0700924 TypeList* interfaces,
David Sehr853a8e12016-09-01 13:03:50 -0700925 const StringId* source_file,
926 AnnotationsDirectoryItem* annotations,
Jeff Hao3ab96b42016-09-09 18:35:01 -0700927 EncodedArrayItem* static_values,
David Sehr853a8e12016-09-01 13:03:50 -0700928 ClassData* class_data)
929 : class_type_(class_type),
930 access_flags_(access_flags),
931 superclass_(superclass),
932 interfaces_(interfaces),
David Sehr853a8e12016-09-01 13:03:50 -0700933 source_file_(source_file),
934 annotations_(annotations),
Jeff Haoa8621002016-10-04 18:13:44 +0000935 class_data_(class_data),
936 static_values_(static_values) { size_ = kClassDefItemSize; }
David Sehr853a8e12016-09-01 13:03:50 -0700937
David Sehr7629f602016-08-07 16:01:51 -0700938 ~ClassDef() OVERRIDE { }
939
Jeff Hao3ab96b42016-09-09 18:35:01 -0700940 static size_t ItemSize() { return kClassDefItemSize; }
941
David Sehr7629f602016-08-07 16:01:51 -0700942 const TypeId* ClassType() const { return class_type_; }
943 uint32_t GetAccessFlags() const { return access_flags_; }
944 const TypeId* Superclass() const { return superclass_; }
Jeff Haocc829592017-03-14 16:13:39 -0700945 const TypeList* Interfaces() { return interfaces_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700946 uint32_t InterfacesOffset() { return interfaces_ == nullptr ? 0 : interfaces_->GetOffset(); }
David Sehr7629f602016-08-07 16:01:51 -0700947 const StringId* SourceFile() const { return source_file_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700948 AnnotationsDirectoryItem* Annotations() const { return annotations_; }
Nicolas Geoffrayfd1a6c22016-10-04 11:01:17 +0000949 ClassData* GetClassData() { return class_data_; }
Jeff Haoa8621002016-10-04 18:13:44 +0000950 EncodedArrayItem* StaticValues() { return static_values_; }
David Sehr7629f602016-08-07 16:01:51 -0700951
Jeff Haoc3acfc52016-08-29 14:18:26 -0700952 MethodItem* GenerateMethodItem(Header& header, ClassDataItemIterator& cdii);
953
David Sehr7629f602016-08-07 16:01:51 -0700954 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
955
956 private:
957 const TypeId* class_type_;
958 uint32_t access_flags_;
Jeff Haoa8621002016-10-04 18:13:44 +0000959 const TypeId* superclass_; // This can be nullptr.
960 TypeList* interfaces_; // This can be nullptr.
961 const StringId* source_file_; // This can be nullptr.
962 AnnotationsDirectoryItem* annotations_; // This can be nullptr.
963 ClassData* class_data_; // This can be nullptr.
964 EncodedArrayItem* static_values_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -0700965
David Sehr7629f602016-08-07 16:01:51 -0700966 DISALLOW_COPY_AND_ASSIGN(ClassDef);
967};
968
Jeff Haoa8621002016-10-04 18:13:44 +0000969class TypeAddrPair {
David Sehr853a8e12016-09-01 13:03:50 -0700970 public:
Jeff Haoa8621002016-10-04 18:13:44 +0000971 TypeAddrPair(const TypeId* type_id, uint32_t address) : type_id_(type_id), address_(address) { }
David Sehr853a8e12016-09-01 13:03:50 -0700972
973 const TypeId* GetTypeId() const { return type_id_; }
974 uint32_t GetAddress() const { return address_; }
975
976 private:
Jeff Haocc829592017-03-14 16:13:39 -0700977 const TypeId* type_id_; // This can be nullptr.
David Sehr853a8e12016-09-01 13:03:50 -0700978 uint32_t address_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700979
Jeff Haoa8621002016-10-04 18:13:44 +0000980 DISALLOW_COPY_AND_ASSIGN(TypeAddrPair);
981};
982
983using TypeAddrPairVector = std::vector<std::unique_ptr<const TypeAddrPair>>;
984
985class CatchHandler {
986 public:
987 explicit CatchHandler(bool catch_all, uint16_t list_offset, TypeAddrPairVector* handlers)
988 : catch_all_(catch_all), list_offset_(list_offset), handlers_(handlers) { }
989
990 bool HasCatchAll() const { return catch_all_; }
991 uint16_t GetListOffset() const { return list_offset_; }
992 TypeAddrPairVector* GetHandlers() const { return handlers_.get(); }
993
994 private:
995 bool catch_all_;
996 uint16_t list_offset_;
997 std::unique_ptr<TypeAddrPairVector> handlers_;
998
David Sehr853a8e12016-09-01 13:03:50 -0700999 DISALLOW_COPY_AND_ASSIGN(CatchHandler);
1000};
1001
1002using CatchHandlerVector = std::vector<std::unique_ptr<const CatchHandler>>;
1003
1004class TryItem : public Item {
1005 public:
Jeff Haoa8621002016-10-04 18:13:44 +00001006 TryItem(uint32_t start_addr, uint16_t insn_count, const CatchHandler* handlers)
David Sehr853a8e12016-09-01 13:03:50 -07001007 : start_addr_(start_addr), insn_count_(insn_count), handlers_(handlers) { }
1008 ~TryItem() OVERRIDE { }
1009
1010 uint32_t StartAddr() const { return start_addr_; }
1011 uint16_t InsnCount() const { return insn_count_; }
Jeff Haoa8621002016-10-04 18:13:44 +00001012 const CatchHandler* GetHandlers() const { return handlers_; }
David Sehr853a8e12016-09-01 13:03:50 -07001013
1014 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1015
1016 private:
1017 uint32_t start_addr_;
1018 uint16_t insn_count_;
Jeff Haoa8621002016-10-04 18:13:44 +00001019 const CatchHandler* handlers_;
Jeff Hao3ab96b42016-09-09 18:35:01 -07001020
David Sehr853a8e12016-09-01 13:03:50 -07001021 DISALLOW_COPY_AND_ASSIGN(TryItem);
1022};
1023
1024using TryItemVector = std::vector<std::unique_ptr<const TryItem>>;
1025
David Sehrd1e44e22016-10-06 17:09:32 -07001026class CodeFixups {
1027 public:
Vladimir Marko219cb902017-12-07 16:20:39 +00001028 CodeFixups(std::vector<TypeId*> type_ids,
1029 std::vector<StringId*> string_ids,
1030 std::vector<MethodId*> method_ids,
1031 std::vector<FieldId*> field_ids)
1032 : type_ids_(std::move(type_ids)),
1033 string_ids_(std::move(string_ids)),
1034 method_ids_(std::move(method_ids)),
1035 field_ids_(std::move(field_ids)) { }
David Sehrd1e44e22016-10-06 17:09:32 -07001036
Vladimir Marko219cb902017-12-07 16:20:39 +00001037 const std::vector<TypeId*>& TypeIds() const { return type_ids_; }
1038 const std::vector<StringId*>& StringIds() const { return string_ids_; }
1039 const std::vector<MethodId*>& MethodIds() const { return method_ids_; }
1040 const std::vector<FieldId*>& FieldIds() const { return field_ids_; }
David Sehrd1e44e22016-10-06 17:09:32 -07001041
1042 private:
Vladimir Marko219cb902017-12-07 16:20:39 +00001043 std::vector<TypeId*> type_ids_;
1044 std::vector<StringId*> string_ids_;
1045 std::vector<MethodId*> method_ids_;
1046 std::vector<FieldId*> field_ids_;
David Sehrd1e44e22016-10-06 17:09:32 -07001047
1048 DISALLOW_COPY_AND_ASSIGN(CodeFixups);
1049};
1050
David Sehr7629f602016-08-07 16:01:51 -07001051class CodeItem : public Item {
1052 public:
David Sehr853a8e12016-09-01 13:03:50 -07001053 CodeItem(uint16_t registers_size,
1054 uint16_t ins_size,
1055 uint16_t outs_size,
1056 DebugInfoItem* debug_info,
1057 uint32_t insns_size,
1058 uint16_t* insns,
Jeff Haoa8621002016-10-04 18:13:44 +00001059 TryItemVector* tries,
1060 CatchHandlerVector* handlers)
David Sehr853a8e12016-09-01 13:03:50 -07001061 : registers_size_(registers_size),
1062 ins_size_(ins_size),
1063 outs_size_(outs_size),
1064 debug_info_(debug_info),
1065 insns_size_(insns_size),
1066 insns_(insns),
Jeff Haoa8621002016-10-04 18:13:44 +00001067 tries_(tries),
1068 handlers_(handlers) { }
David Sehr853a8e12016-09-01 13:03:50 -07001069
David Sehr7629f602016-08-07 16:01:51 -07001070 ~CodeItem() OVERRIDE { }
1071
1072 uint16_t RegistersSize() const { return registers_size_; }
1073 uint16_t InsSize() const { return ins_size_; }
1074 uint16_t OutsSize() const { return outs_size_; }
David Sehr853a8e12016-09-01 13:03:50 -07001075 uint16_t TriesSize() const { return tries_ == nullptr ? 0 : tries_->size(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -07001076 DebugInfoItem* DebugInfo() const { return debug_info_; }
David Sehr7629f602016-08-07 16:01:51 -07001077 uint32_t InsnsSize() const { return insns_size_; }
1078 uint16_t* Insns() const { return insns_.get(); }
David Sehr853a8e12016-09-01 13:03:50 -07001079 TryItemVector* Tries() const { return tries_.get(); }
Jeff Haoa8621002016-10-04 18:13:44 +00001080 CatchHandlerVector* Handlers() const { return handlers_.get(); }
David Sehr7629f602016-08-07 16:01:51 -07001081
David Sehrd1e44e22016-10-06 17:09:32 -07001082 void SetCodeFixups(CodeFixups* fixups) { fixups_.reset(fixups); }
1083 CodeFixups* GetCodeFixups() const { return fixups_.get(); }
1084
David Sehr7629f602016-08-07 16:01:51 -07001085 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1086
Mathieu Chartier1d2d4ff2017-09-23 16:11:06 -07001087 IterationRange<DexInstructionIterator> Instructions() const {
Mathieu Chartier2b2bef22017-10-26 17:10:19 -07001088 return MakeIterationRange(DexInstructionIterator(Insns(), 0u),
1089 DexInstructionIterator(Insns(), InsnsSize()));
Mathieu Chartier1d2d4ff2017-09-23 16:11:06 -07001090 }
1091
David Sehr7629f602016-08-07 16:01:51 -07001092 private:
1093 uint16_t registers_size_;
1094 uint16_t ins_size_;
1095 uint16_t outs_size_;
Jeff Haoa8621002016-10-04 18:13:44 +00001096 DebugInfoItem* debug_info_; // This can be nullptr.
David Sehr7629f602016-08-07 16:01:51 -07001097 uint32_t insns_size_;
1098 std::unique_ptr<uint16_t[]> insns_;
Jeff Haoa8621002016-10-04 18:13:44 +00001099 std::unique_ptr<TryItemVector> tries_; // This can be nullptr.
1100 std::unique_ptr<CatchHandlerVector> handlers_; // This can be nullptr.
David Sehrd1e44e22016-10-06 17:09:32 -07001101 std::unique_ptr<CodeFixups> fixups_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -07001102
David Sehr7629f602016-08-07 16:01:51 -07001103 DISALLOW_COPY_AND_ASSIGN(CodeItem);
1104};
1105
David Sehr7629f602016-08-07 16:01:51 -07001106class DebugInfoItem : public Item {
1107 public:
Jeff Haoa8621002016-10-04 18:13:44 +00001108 DebugInfoItem(uint32_t debug_info_size, uint8_t* debug_info)
1109 : debug_info_size_(debug_info_size), debug_info_(debug_info) { }
1110
1111 uint32_t GetDebugInfoSize() const { return debug_info_size_; }
1112 uint8_t* GetDebugInfo() const { return debug_info_.get(); }
David Sehr7629f602016-08-07 16:01:51 -07001113
David Sehr7629f602016-08-07 16:01:51 -07001114 private:
Jeff Haoa8621002016-10-04 18:13:44 +00001115 uint32_t debug_info_size_;
1116 std::unique_ptr<uint8_t[]> debug_info_;
1117
David Sehr7629f602016-08-07 16:01:51 -07001118 DISALLOW_COPY_AND_ASSIGN(DebugInfoItem);
1119};
1120
Jeff Hao3ab96b42016-09-09 18:35:01 -07001121class AnnotationItem : public Item {
David Sehr853a8e12016-09-01 13:03:50 -07001122 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -07001123 AnnotationItem(uint8_t visibility, EncodedAnnotation* annotation)
1124 : visibility_(visibility), annotation_(annotation) { }
David Sehr853a8e12016-09-01 13:03:50 -07001125
1126 uint8_t GetVisibility() const { return visibility_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -07001127 EncodedAnnotation* GetAnnotation() const { return annotation_.get(); }
David Sehr7629f602016-08-07 16:01:51 -07001128
1129 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1130
1131 private:
Jeff Hao3ab96b42016-09-09 18:35:01 -07001132 uint8_t visibility_;
1133 std::unique_ptr<EncodedAnnotation> annotation_;
1134
1135 DISALLOW_COPY_AND_ASSIGN(AnnotationItem);
1136};
1137
1138class AnnotationSetItem : public Item {
1139 public:
1140 explicit AnnotationSetItem(std::vector<AnnotationItem*>* items) : items_(items) {
1141 size_ = sizeof(uint32_t) + items->size() * sizeof(uint32_t);
1142 }
1143 ~AnnotationSetItem() OVERRIDE { }
1144
1145 std::vector<AnnotationItem*>* GetItems() { return items_.get(); }
1146
1147 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1148
1149 private:
1150 std::unique_ptr<std::vector<AnnotationItem*>> items_;
1151
David Sehr7629f602016-08-07 16:01:51 -07001152 DISALLOW_COPY_AND_ASSIGN(AnnotationSetItem);
1153};
1154
Jeff Hao3ab96b42016-09-09 18:35:01 -07001155class AnnotationSetRefList : public Item {
1156 public:
1157 explicit AnnotationSetRefList(std::vector<AnnotationSetItem*>* items) : items_(items) {
1158 size_ = sizeof(uint32_t) + items->size() * sizeof(uint32_t);
1159 }
1160 ~AnnotationSetRefList() OVERRIDE { }
1161
1162 std::vector<AnnotationSetItem*>* GetItems() { return items_.get(); }
1163
1164 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1165
1166 private:
Jeff Haoa8621002016-10-04 18:13:44 +00001167 std::unique_ptr<std::vector<AnnotationSetItem*>> items_; // Elements of vector can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -07001168
1169 DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefList);
1170};
David Sehr853a8e12016-09-01 13:03:50 -07001171
1172class FieldAnnotation {
1173 public:
1174 FieldAnnotation(FieldId* field_id, AnnotationSetItem* annotation_set_item)
1175 : field_id_(field_id), annotation_set_item_(annotation_set_item) { }
1176
1177 FieldId* GetFieldId() const { return field_id_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -07001178 AnnotationSetItem* GetAnnotationSetItem() const { return annotation_set_item_; }
David Sehr853a8e12016-09-01 13:03:50 -07001179
1180 private:
1181 FieldId* field_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -07001182 AnnotationSetItem* annotation_set_item_;
1183
David Sehr853a8e12016-09-01 13:03:50 -07001184 DISALLOW_COPY_AND_ASSIGN(FieldAnnotation);
1185};
1186
1187using FieldAnnotationVector = std::vector<std::unique_ptr<FieldAnnotation>>;
1188
1189class MethodAnnotation {
1190 public:
1191 MethodAnnotation(MethodId* method_id, AnnotationSetItem* annotation_set_item)
1192 : method_id_(method_id), annotation_set_item_(annotation_set_item) { }
1193
1194 MethodId* GetMethodId() const { return method_id_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -07001195 AnnotationSetItem* GetAnnotationSetItem() const { return annotation_set_item_; }
David Sehr853a8e12016-09-01 13:03:50 -07001196
1197 private:
1198 MethodId* method_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -07001199 AnnotationSetItem* annotation_set_item_;
1200
David Sehr853a8e12016-09-01 13:03:50 -07001201 DISALLOW_COPY_AND_ASSIGN(MethodAnnotation);
1202};
1203
1204using MethodAnnotationVector = std::vector<std::unique_ptr<MethodAnnotation>>;
1205
1206class ParameterAnnotation {
1207 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -07001208 ParameterAnnotation(MethodId* method_id, AnnotationSetRefList* annotations)
David Sehr853a8e12016-09-01 13:03:50 -07001209 : method_id_(method_id), annotations_(annotations) { }
1210
1211 MethodId* GetMethodId() const { return method_id_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -07001212 AnnotationSetRefList* GetAnnotations() { return annotations_; }
David Sehr853a8e12016-09-01 13:03:50 -07001213
1214 private:
1215 MethodId* method_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -07001216 AnnotationSetRefList* annotations_;
1217
David Sehr853a8e12016-09-01 13:03:50 -07001218 DISALLOW_COPY_AND_ASSIGN(ParameterAnnotation);
1219};
1220
1221using ParameterAnnotationVector = std::vector<std::unique_ptr<ParameterAnnotation>>;
1222
David Sehr7629f602016-08-07 16:01:51 -07001223class AnnotationsDirectoryItem : public Item {
1224 public:
David Sehr853a8e12016-09-01 13:03:50 -07001225 AnnotationsDirectoryItem(AnnotationSetItem* class_annotation,
1226 FieldAnnotationVector* field_annotations,
1227 MethodAnnotationVector* method_annotations,
1228 ParameterAnnotationVector* parameter_annotations)
1229 : class_annotation_(class_annotation),
1230 field_annotations_(field_annotations),
1231 method_annotations_(method_annotations),
1232 parameter_annotations_(parameter_annotations) { }
David Sehr7629f602016-08-07 16:01:51 -07001233
Jeff Hao3ab96b42016-09-09 18:35:01 -07001234 AnnotationSetItem* GetClassAnnotation() const { return class_annotation_; }
David Sehr853a8e12016-09-01 13:03:50 -07001235 FieldAnnotationVector* GetFieldAnnotations() { return field_annotations_.get(); }
1236 MethodAnnotationVector* GetMethodAnnotations() { return method_annotations_.get(); }
1237 ParameterAnnotationVector* GetParameterAnnotations() { return parameter_annotations_.get(); }
David Sehr7629f602016-08-07 16:01:51 -07001238
1239 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1240
1241 private:
Jeff Haoa8621002016-10-04 18:13:44 +00001242 AnnotationSetItem* class_annotation_; // This can be nullptr.
1243 std::unique_ptr<FieldAnnotationVector> field_annotations_; // This can be nullptr.
1244 std::unique_ptr<MethodAnnotationVector> method_annotations_; // This can be nullptr.
1245 std::unique_ptr<ParameterAnnotationVector> parameter_annotations_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -07001246
David Sehr7629f602016-08-07 16:01:51 -07001247 DISALLOW_COPY_AND_ASSIGN(AnnotationsDirectoryItem);
1248};
1249
Jeff Hao5daee902017-04-27 18:00:38 -07001250class CallSiteId : public IndexedItem {
1251 public:
1252 explicit CallSiteId(EncodedArrayItem* call_site_item) : call_site_item_(call_site_item) {
1253 size_ = kCallSiteIdItemSize;
1254 }
1255 ~CallSiteId() OVERRIDE { }
1256
1257 static size_t ItemSize() { return kCallSiteIdItemSize; }
1258
1259 EncodedArrayItem* CallSiteItem() const { return call_site_item_; }
1260
1261 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
1262
1263 private:
1264 EncodedArrayItem* call_site_item_;
1265
1266 DISALLOW_COPY_AND_ASSIGN(CallSiteId);
1267};
1268
1269class MethodHandleItem : public IndexedItem {
1270 public:
1271 MethodHandleItem(DexFile::MethodHandleType method_handle_type, IndexedItem* field_or_method_id)
1272 : method_handle_type_(method_handle_type),
1273 field_or_method_id_(field_or_method_id) {
1274 size_ = kMethodHandleItemSize;
1275 }
1276 ~MethodHandleItem() OVERRIDE { }
1277
1278 static size_t ItemSize() { return kMethodHandleItemSize; }
1279
1280 DexFile::MethodHandleType GetMethodHandleType() const { return method_handle_type_; }
1281 IndexedItem* GetFieldOrMethodId() const { return field_or_method_id_; }
1282
1283 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
1284
1285 private:
1286 DexFile::MethodHandleType method_handle_type_;
1287 IndexedItem* field_or_method_id_;
1288
1289 DISALLOW_COPY_AND_ASSIGN(MethodHandleItem);
1290};
1291
David Sehr7629f602016-08-07 16:01:51 -07001292// TODO(sehr): implement MapList.
1293class MapList : public Item {
1294 public:
1295 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1296
1297 private:
1298 DISALLOW_COPY_AND_ASSIGN(MapList);
1299};
1300
1301class MapItem : public Item {
1302 public:
1303 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1304
1305 private:
1306 DISALLOW_COPY_AND_ASSIGN(MapItem);
1307};
1308
David Sehr9037a3a2017-03-30 17:50:24 -07001309// Interface for building a vector of file sections for use by other clients.
1310struct DexFileSection {
1311 public:
1312 DexFileSection(const std::string& name, uint16_t type, uint32_t size, uint32_t offset)
1313 : name(name), type(type), size(size), offset(offset) { }
1314 std::string name;
1315 // The type (DexFile::MapItemType).
1316 uint16_t type;
1317 // The size (in elements, not bytes).
1318 uint32_t size;
1319 // The byte offset from the start of the file.
1320 uint32_t offset;
1321};
1322
1323enum class SortDirection {
1324 kSortAscending,
1325 kSortDescending
1326};
1327
1328std::vector<DexFileSection> GetSortedDexFileSections(dex_ir::Header* header,
1329 SortDirection direction);
1330
David Sehr7629f602016-08-07 16:01:51 -07001331} // namespace dex_ir
1332} // namespace art
1333
1334#endif // ART_DEXLAYOUT_DEX_IR_H_