blob: 5ecad2bf87f8db7e3ce7cfc540643ba49fead1a1 [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
David Sehr67bf42e2018-02-26 16:43:04 -080027#include "base/leb128.h"
Andreas Gampe5678db52017-06-08 14:11:18 -070028#include "base/stl_util.h"
David Sehr9e734c72018-01-04 17:56:19 -080029#include "dex/dex_file-inl.h"
30#include "dex/dex_file_types.h"
David Sehr0225f8e2018-01-31 08:52:24 +000031#include "dex/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
Mathieu Chartier66c9df12018-01-16 14:45:20 -0800138 // Sort the vector by copying pointers over.
139 template <typename MapType>
140 void SortByMapOrder(const MapType& map) {
141 auto it = map.begin();
142 CHECK_EQ(map.size(), Size());
143 for (size_t i = 0; i < Size(); ++i) {
144 // There are times when the array will temporarily contain the same pointer twice, doing the
145 // release here sure there is no double free errors.
146 Collection()[i].release();
147 Collection()[i].reset(it->second);
148 ++it;
149 }
150 }
151
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800152 protected:
153 Vector collection_;
154
155 void AddItem(T* object) {
Jeff Hao3ab96b42016-09-09 18:35:01 -0700156 collection_.push_back(std::unique_ptr<T>(object));
David Sehr7629f602016-08-07 16:01:51 -0700157 }
David Sehr7629f602016-08-07 16:01:51 -0700158
159 private:
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800160 friend class Collections;
Jeff Haoea7c6292016-11-14 18:10:16 -0800161 DISALLOW_COPY_AND_ASSIGN(CollectionVector);
162};
163
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800164template<class T> class IndexedCollectionVector : public CollectionVector<T> {
165 public:
166 using Vector = std::vector<std::unique_ptr<T>>;
167 IndexedCollectionVector() = default;
168
169 private:
170 void AddIndexedItem(T* object, uint32_t index) {
171 object->SetIndex(index);
172 CollectionVector<T>::collection_.push_back(std::unique_ptr<T>(object));
173 }
174
175 friend class Collections;
176 DISALLOW_COPY_AND_ASSIGN(IndexedCollectionVector);
177};
178
Jeff Haoea7c6292016-11-14 18:10:16 -0800179template<class T> class CollectionMap : public CollectionBase<T> {
180 public:
181 CollectionMap() = default;
182
Mathieu Chartiera2973d72017-02-14 17:12:20 -0800183 // Returns the existing item if it is already inserted, null otherwise.
184 T* GetExistingObject(uint32_t offset) {
185 auto it = collection_.find(offset);
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800186 return it != collection_.end() ? it->second : nullptr;
Mathieu Chartiera2973d72017-02-14 17:12:20 -0800187 }
188
Mathieu Chartier66c9df12018-01-16 14:45:20 -0800189 // Lower case for template interop with std::map.
190 uint32_t size() const { return collection_.size(); }
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800191 std::map<uint32_t, T*>& Collection() { return collection_; }
192
Jeff Haoea7c6292016-11-14 18:10:16 -0800193 private:
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800194 std::map<uint32_t, T*> collection_;
Jeff Haoea7c6292016-11-14 18:10:16 -0800195
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800196 void AddItem(T* object, uint32_t offset) {
197 auto it = collection_.emplace(offset, object);
198 CHECK(it.second) << "CollectionMap already has an object with offset " << offset << " "
199 << " and address " << it.first->second;
200 }
201
202 friend class Collections;
Jeff Haoea7c6292016-11-14 18:10:16 -0800203 DISALLOW_COPY_AND_ASSIGN(CollectionMap);
David Sehr7629f602016-08-07 16:01:51 -0700204};
205
Jeff Hao3ab96b42016-09-09 18:35:01 -0700206class Collections {
207 public:
208 Collections() = default;
209
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800210 CollectionVector<StringId>::Vector& StringIds() { return string_ids_.Collection(); }
211 CollectionVector<TypeId>::Vector& TypeIds() { return type_ids_.Collection(); }
212 CollectionVector<ProtoId>::Vector& ProtoIds() { return proto_ids_.Collection(); }
213 CollectionVector<FieldId>::Vector& FieldIds() { return field_ids_.Collection(); }
214 CollectionVector<MethodId>::Vector& MethodIds() { return method_ids_.Collection(); }
215 CollectionVector<ClassDef>::Vector& ClassDefs() { return class_defs_.Collection(); }
216 CollectionVector<CallSiteId>::Vector& CallSiteIds() { return call_site_ids_.Collection(); }
217 CollectionVector<MethodHandleItem>::Vector& MethodHandleItems()
Jeff Hao5daee902017-04-27 18:00:38 -0700218 { return method_handle_items_.Collection(); }
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800219 CollectionVector<StringData>::Vector& StringDatas() { return string_datas_.Collection(); }
220 CollectionVector<TypeList>::Vector& TypeLists() { return type_lists_.Collection(); }
221 CollectionVector<EncodedArrayItem>::Vector& EncodedArrayItems()
Jeff Hao3ab96b42016-09-09 18:35:01 -0700222 { return encoded_array_items_.Collection(); }
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800223 CollectionVector<AnnotationItem>::Vector& AnnotationItems()
Jeff Haoa8621002016-10-04 18:13:44 +0000224 { return annotation_items_.Collection(); }
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800225 CollectionVector<AnnotationSetItem>::Vector& AnnotationSetItems()
Jeff Haoa8621002016-10-04 18:13:44 +0000226 { return annotation_set_items_.Collection(); }
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800227 CollectionVector<AnnotationSetRefList>::Vector& AnnotationSetRefLists()
Jeff Haoa8621002016-10-04 18:13:44 +0000228 { return annotation_set_ref_lists_.Collection(); }
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800229 CollectionVector<AnnotationsDirectoryItem>::Vector& AnnotationsDirectoryItems()
Jeff Haoa8621002016-10-04 18:13:44 +0000230 { return annotations_directory_items_.Collection(); }
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800231 CollectionVector<DebugInfoItem>::Vector& DebugInfoItems()
Jeff Haoa8621002016-10-04 18:13:44 +0000232 { return debug_info_items_.Collection(); }
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800233 CollectionVector<CodeItem>::Vector& CodeItems() { return code_items_.Collection(); }
234 CollectionVector<ClassData>::Vector& ClassDatas() { return class_datas_.Collection(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700235
Mathieu Chartier8892c6b2018-01-09 15:10:17 -0800236 const CollectionVector<ClassDef>::Vector& ClassDefs() const { return class_defs_.Collection(); }
237
Jeff Hao3ab96b42016-09-09 18:35:01 -0700238 void CreateStringId(const DexFile& dex_file, uint32_t i);
239 void CreateTypeId(const DexFile& dex_file, uint32_t i);
240 void CreateProtoId(const DexFile& dex_file, uint32_t i);
241 void CreateFieldId(const DexFile& dex_file, uint32_t i);
242 void CreateMethodId(const DexFile& dex_file, uint32_t i);
243 void CreateClassDef(const DexFile& dex_file, uint32_t i);
Jeff Hao5daee902017-04-27 18:00:38 -0700244 void CreateCallSiteId(const DexFile& dex_file, uint32_t i);
245 void CreateMethodHandleItem(const DexFile& dex_file, uint32_t i);
246
247 void CreateCallSitesAndMethodHandles(const DexFile& dex_file);
Jeff Hao3ab96b42016-09-09 18:35:01 -0700248
Jeff Haoa8621002016-10-04 18:13:44 +0000249 TypeList* CreateTypeList(const DexFile::TypeList* type_list, uint32_t offset);
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800250 EncodedArrayItem* CreateEncodedArrayItem(const DexFile& dex_file,
251 const uint8_t* static_data,
252 uint32_t offset);
Mathieu Chartier24066ec2017-10-21 16:01:08 -0700253 AnnotationItem* CreateAnnotationItem(const DexFile& dex_file,
254 const DexFile::AnnotationItem* annotation);
Jeff Hao3ab96b42016-09-09 18:35:01 -0700255 AnnotationSetItem* CreateAnnotationSetItem(const DexFile& dex_file,
Jeff Haobe9b44b2017-02-16 13:34:38 -0800256 const DexFile::AnnotationSetItem* disk_annotations_item, uint32_t offset);
Jeff Hao3ab96b42016-09-09 18:35:01 -0700257 AnnotationsDirectoryItem* CreateAnnotationsDirectoryItem(const DexFile& dex_file,
258 const DexFile::AnnotationsDirectoryItem* disk_annotations_item, uint32_t offset);
Mathieu Chartier66c9df12018-01-16 14:45:20 -0800259 CodeItem* DedupeOrCreateCodeItem(const DexFile& dex_file,
260 const DexFile::CodeItem* disk_code_item,
261 uint32_t offset,
262 uint32_t dex_method_index);
Jeff Hao3ab96b42016-09-09 18:35:01 -0700263 ClassData* CreateClassData(const DexFile& dex_file, const uint8_t* encoded_data, uint32_t offset);
Mathieu Chartier24066ec2017-10-21 16:01:08 -0700264 void AddAnnotationsFromMapListSection(const DexFile& dex_file,
265 uint32_t start_offset,
266 uint32_t count);
Jeff Hao3ab96b42016-09-09 18:35:01 -0700267
Jeff Hao9804e9e2017-06-15 14:04:51 -0700268 StringId* GetStringId(uint32_t index) {
269 CHECK_LT(index, StringIdsSize());
270 return StringIds()[index].get();
271 }
272 TypeId* GetTypeId(uint32_t index) {
273 CHECK_LT(index, TypeIdsSize());
274 return TypeIds()[index].get();
275 }
276 ProtoId* GetProtoId(uint32_t index) {
277 CHECK_LT(index, ProtoIdsSize());
278 return ProtoIds()[index].get();
279 }
280 FieldId* GetFieldId(uint32_t index) {
281 CHECK_LT(index, FieldIdsSize());
282 return FieldIds()[index].get();
283 }
284 MethodId* GetMethodId(uint32_t index) {
285 CHECK_LT(index, MethodIdsSize());
286 return MethodIds()[index].get();
287 }
288 ClassDef* GetClassDef(uint32_t index) {
289 CHECK_LT(index, ClassDefsSize());
290 return ClassDefs()[index].get();
291 }
292 CallSiteId* GetCallSiteId(uint32_t index) {
293 CHECK_LT(index, CallSiteIdsSize());
294 return CallSiteIds()[index].get();
295 }
296 MethodHandleItem* GetMethodHandle(uint32_t index) {
297 CHECK_LT(index, MethodHandleItemsSize());
298 return MethodHandleItems()[index].get();
299 }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700300
301 StringId* GetStringIdOrNullPtr(uint32_t index) {
Andreas Gampee2abbc62017-09-15 11:59:26 -0700302 return index == dex::kDexNoIndex ? nullptr : GetStringId(index);
Jeff Hao3ab96b42016-09-09 18:35:01 -0700303 }
304 TypeId* GetTypeIdOrNullPtr(uint16_t index) {
305 return index == DexFile::kDexNoIndex16 ? nullptr : GetTypeId(index);
306 }
307
308 uint32_t StringIdsOffset() const { return string_ids_.GetOffset(); }
309 uint32_t TypeIdsOffset() const { return type_ids_.GetOffset(); }
310 uint32_t ProtoIdsOffset() const { return proto_ids_.GetOffset(); }
311 uint32_t FieldIdsOffset() const { return field_ids_.GetOffset(); }
312 uint32_t MethodIdsOffset() const { return method_ids_.GetOffset(); }
313 uint32_t ClassDefsOffset() const { return class_defs_.GetOffset(); }
Jeff Hao5daee902017-04-27 18:00:38 -0700314 uint32_t CallSiteIdsOffset() const { return call_site_ids_.GetOffset(); }
315 uint32_t MethodHandleItemsOffset() const { return method_handle_items_.GetOffset(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700316 uint32_t StringDatasOffset() const { return string_datas_.GetOffset(); }
317 uint32_t TypeListsOffset() const { return type_lists_.GetOffset(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000318 uint32_t EncodedArrayItemsOffset() const { return encoded_array_items_.GetOffset(); }
319 uint32_t AnnotationItemsOffset() const { return annotation_items_.GetOffset(); }
320 uint32_t AnnotationSetItemsOffset() const { return annotation_set_items_.GetOffset(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700321 uint32_t AnnotationSetRefListsOffset() const { return annotation_set_ref_lists_.GetOffset(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000322 uint32_t AnnotationsDirectoryItemsOffset() const
323 { return annotations_directory_items_.GetOffset(); }
324 uint32_t DebugInfoItemsOffset() const { return debug_info_items_.GetOffset(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700325 uint32_t CodeItemsOffset() const { return code_items_.GetOffset(); }
326 uint32_t ClassDatasOffset() const { return class_datas_.GetOffset(); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800327 uint32_t MapListOffset() const { return map_list_offset_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700328
329 void SetStringIdsOffset(uint32_t new_offset) { string_ids_.SetOffset(new_offset); }
330 void SetTypeIdsOffset(uint32_t new_offset) { type_ids_.SetOffset(new_offset); }
331 void SetProtoIdsOffset(uint32_t new_offset) { proto_ids_.SetOffset(new_offset); }
332 void SetFieldIdsOffset(uint32_t new_offset) { field_ids_.SetOffset(new_offset); }
333 void SetMethodIdsOffset(uint32_t new_offset) { method_ids_.SetOffset(new_offset); }
334 void SetClassDefsOffset(uint32_t new_offset) { class_defs_.SetOffset(new_offset); }
Jeff Hao5daee902017-04-27 18:00:38 -0700335 void SetCallSiteIdsOffset(uint32_t new_offset) { call_site_ids_.SetOffset(new_offset); }
336 void SetMethodHandleItemsOffset(uint32_t new_offset)
337 { method_handle_items_.SetOffset(new_offset); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700338 void SetStringDatasOffset(uint32_t new_offset) { string_datas_.SetOffset(new_offset); }
339 void SetTypeListsOffset(uint32_t new_offset) { type_lists_.SetOffset(new_offset); }
Jeff Haoa8621002016-10-04 18:13:44 +0000340 void SetEncodedArrayItemsOffset(uint32_t new_offset)
341 { encoded_array_items_.SetOffset(new_offset); }
342 void SetAnnotationItemsOffset(uint32_t new_offset) { annotation_items_.SetOffset(new_offset); }
343 void SetAnnotationSetItemsOffset(uint32_t new_offset)
344 { annotation_set_items_.SetOffset(new_offset); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700345 void SetAnnotationSetRefListsOffset(uint32_t new_offset)
346 { annotation_set_ref_lists_.SetOffset(new_offset); }
Jeff Haoa8621002016-10-04 18:13:44 +0000347 void SetAnnotationsDirectoryItemsOffset(uint32_t new_offset)
Jeff Hao3ab96b42016-09-09 18:35:01 -0700348 { annotations_directory_items_.SetOffset(new_offset); }
Jeff Haoa8621002016-10-04 18:13:44 +0000349 void SetDebugInfoItemsOffset(uint32_t new_offset) { debug_info_items_.SetOffset(new_offset); }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700350 void SetCodeItemsOffset(uint32_t new_offset) { code_items_.SetOffset(new_offset); }
351 void SetClassDatasOffset(uint32_t new_offset) { class_datas_.SetOffset(new_offset); }
Jeff Haoea7c6292016-11-14 18:10:16 -0800352 void SetMapListOffset(uint32_t new_offset) { map_list_offset_ = new_offset; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700353
354 uint32_t StringIdsSize() const { return string_ids_.Size(); }
355 uint32_t TypeIdsSize() const { return type_ids_.Size(); }
356 uint32_t ProtoIdsSize() const { return proto_ids_.Size(); }
357 uint32_t FieldIdsSize() const { return field_ids_.Size(); }
358 uint32_t MethodIdsSize() const { return method_ids_.Size(); }
359 uint32_t ClassDefsSize() const { return class_defs_.Size(); }
Jeff Hao5daee902017-04-27 18:00:38 -0700360 uint32_t CallSiteIdsSize() const { return call_site_ids_.Size(); }
361 uint32_t MethodHandleItemsSize() const { return method_handle_items_.Size(); }
David Sehrcdcfde72016-09-26 07:44:04 -0700362 uint32_t StringDatasSize() const { return string_datas_.Size(); }
363 uint32_t TypeListsSize() const { return type_lists_.Size(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000364 uint32_t EncodedArrayItemsSize() const { return encoded_array_items_.Size(); }
365 uint32_t AnnotationItemsSize() const { return annotation_items_.Size(); }
366 uint32_t AnnotationSetItemsSize() const { return annotation_set_items_.Size(); }
David Sehrcdcfde72016-09-26 07:44:04 -0700367 uint32_t AnnotationSetRefListsSize() const { return annotation_set_ref_lists_.Size(); }
Jeff Haoa8621002016-10-04 18:13:44 +0000368 uint32_t AnnotationsDirectoryItemsSize() const { return annotations_directory_items_.Size(); }
369 uint32_t DebugInfoItemsSize() const { return debug_info_items_.Size(); }
David Sehrcdcfde72016-09-26 07:44:04 -0700370 uint32_t CodeItemsSize() const { return code_items_.Size(); }
371 uint32_t ClassDatasSize() const { return class_datas_.Size(); }
372
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800373 // Sort the vectors buy map order (same order that was used in the input file).
374 void SortVectorsByMapOrder();
375
376 template <typename Type>
377 void AddItem(CollectionMap<Type>& map,
378 CollectionVector<Type>& vector,
379 Type* item,
380 uint32_t offset) {
381 DCHECK(!map.GetExistingObject(offset));
382 DCHECK(!item->OffsetAssigned());
383 if (eagerly_assign_offsets_) {
384 item->SetOffset(offset);
385 }
386 map.AddItem(item, offset);
387 vector.AddItem(item);
388 }
389
390 template <typename Type>
391 void AddIndexedItem(IndexedCollectionVector<Type>& vector,
392 Type* item,
393 uint32_t offset,
394 uint32_t index) {
395 DCHECK(!item->OffsetAssigned());
396 if (eagerly_assign_offsets_) {
397 item->SetOffset(offset);
398 }
399 vector.AddIndexedItem(item, index);
400 }
401
402 void SetEagerlyAssignOffsets(bool eagerly_assign_offsets) {
403 eagerly_assign_offsets_ = eagerly_assign_offsets;
404 }
405
Mathieu Chartier2f36d2f2017-11-20 15:45:25 -0800406 void SetLinkData(std::vector<uint8_t>&& link_data) {
407 link_data_ = std::move(link_data);
408 }
409
410 const std::vector<uint8_t>& LinkData() const {
411 return link_data_;
412 }
413
Jeff Hao3ab96b42016-09-09 18:35:01 -0700414 private:
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800415 EncodedValue* ReadEncodedValue(const DexFile& dex_file, const uint8_t** data);
416 EncodedValue* ReadEncodedValue(const DexFile& dex_file,
417 const uint8_t** data,
418 uint8_t type,
419 uint8_t length);
420 void ReadEncodedValue(const DexFile& dex_file,
421 const uint8_t** data,
422 uint8_t type,
423 uint8_t length,
424 EncodedValue* item);
Jeff Hao3ab96b42016-09-09 18:35:01 -0700425
426 ParameterAnnotation* GenerateParameterAnnotation(const DexFile& dex_file, MethodId* method_id,
427 const DexFile::AnnotationSetRefList* annotation_set_ref_list, uint32_t offset);
428 MethodItem* GenerateMethodItem(const DexFile& dex_file, ClassDataItemIterator& cdii);
429
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800430 // Collection vectors own the IR data.
431 IndexedCollectionVector<StringId> string_ids_;
432 IndexedCollectionVector<TypeId> type_ids_;
433 IndexedCollectionVector<ProtoId> proto_ids_;
434 IndexedCollectionVector<FieldId> field_ids_;
435 IndexedCollectionVector<MethodId> method_ids_;
436 IndexedCollectionVector<CallSiteId> call_site_ids_;
437 IndexedCollectionVector<MethodHandleItem> method_handle_items_;
438 IndexedCollectionVector<StringData> string_datas_;
439 IndexedCollectionVector<TypeList> type_lists_;
440 IndexedCollectionVector<EncodedArrayItem> encoded_array_items_;
441 IndexedCollectionVector<AnnotationItem> annotation_items_;
442 IndexedCollectionVector<AnnotationSetItem> annotation_set_items_;
443 IndexedCollectionVector<AnnotationSetRefList> annotation_set_ref_lists_;
444 IndexedCollectionVector<AnnotationsDirectoryItem> annotations_directory_items_;
445 IndexedCollectionVector<ClassDef> class_defs_;
446 // The order of the vectors controls the layout of the output file by index order, to change the
447 // layout just sort the vector. Note that you may only change the order of the non indexed vectors
448 // below. Indexed vectors are accessed by indices in other places, changing the sorting order will
449 // invalidate the existing indices and is not currently supported.
450 CollectionVector<DebugInfoItem> debug_info_items_;
451 CollectionVector<CodeItem> code_items_;
452 CollectionVector<ClassData> class_datas_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700453
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800454 // Note that the maps do not have ownership, the vectors do.
455 // TODO: These maps should only be required for building the IR and should be put in a separate
456 // IR builder class.
457 CollectionMap<StringData> string_datas_map_;
458 CollectionMap<TypeList> type_lists_map_;
459 CollectionMap<EncodedArrayItem> encoded_array_items_map_;
460 CollectionMap<AnnotationItem> annotation_items_map_;
461 CollectionMap<AnnotationSetItem> annotation_set_items_map_;
462 CollectionMap<AnnotationSetRefList> annotation_set_ref_lists_map_;
463 CollectionMap<AnnotationsDirectoryItem> annotations_directory_items_map_;
464 CollectionMap<DebugInfoItem> debug_info_items_map_;
Mathieu Chartier66c9df12018-01-16 14:45:20 -0800465 // Code item maps need to check both the debug info offset and debug info offset, do not use
466 // CollectionMap.
467 // First offset is the code item offset, second is the debug info offset.
468 std::map<std::pair<uint32_t, uint32_t>, CodeItem*> code_items_map_;
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800469 CollectionMap<ClassData> class_datas_map_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700470
Jeff Haoea7c6292016-11-14 18:10:16 -0800471 uint32_t map_list_offset_ = 0;
Jeff Haoa8621002016-10-04 18:13:44 +0000472
Mathieu Chartier2f36d2f2017-11-20 15:45:25 -0800473 // Link data.
474 std::vector<uint8_t> link_data_;
475
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800476 // If we eagerly assign offsets during IR building or later after layout. Must be false if
477 // changing the layout is enabled.
478 bool eagerly_assign_offsets_;
479
Jeff Hao3ab96b42016-09-09 18:35:01 -0700480 DISALLOW_COPY_AND_ASSIGN(Collections);
481};
482
David Sehr7629f602016-08-07 16:01:51 -0700483class Item {
484 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700485 Item() { }
David Sehr7629f602016-08-07 16:01:51 -0700486 virtual ~Item() { }
David Sehr853a8e12016-09-01 13:03:50 -0700487
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800488 // Return the assigned offset.
Mathieu Chartiere6b6ff82018-01-19 18:58:34 -0800489 uint32_t GetOffset() const WARN_UNUSED {
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800490 CHECK(OffsetAssigned());
491 return offset_;
492 }
Mathieu Chartiere6b6ff82018-01-19 18:58:34 -0800493 uint32_t GetSize() const WARN_UNUSED { return size_; }
David Sehr7629f602016-08-07 16:01:51 -0700494 void SetOffset(uint32_t offset) { offset_ = offset; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700495 void SetSize(uint32_t size) { size_ = size; }
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800496 bool OffsetAssigned() const {
497 return offset_ != kOffsetUnassigned;
498 }
David Sehr853a8e12016-09-01 13:03:50 -0700499
David Sehr7629f602016-08-07 16:01:51 -0700500 protected:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700501 Item(uint32_t offset, uint32_t size) : offset_(offset), size_(size) { }
502
Mathieu Chartier3e0c5172017-11-12 12:58:40 -0800503 // 0 is the dex file header and shouldn't be a valid offset for any part of the dex file.
504 static constexpr uint32_t kOffsetUnassigned = 0u;
505
506 // Start out unassigned.
507 uint32_t offset_ = kOffsetUnassigned;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700508 uint32_t size_ = 0;
509};
510
511class IndexedItem : public Item {
512 public:
513 IndexedItem() { }
514 virtual ~IndexedItem() { }
515
516 uint32_t GetIndex() const { return index_; }
517 void SetIndex(uint32_t index) { index_ = index; }
518
519 protected:
520 IndexedItem(uint32_t offset, uint32_t size, uint32_t index)
521 : Item(offset, size), index_(index) { }
522
523 uint32_t index_ = 0;
David Sehr7629f602016-08-07 16:01:51 -0700524};
525
526class Header : public Item {
527 public:
David Sehr853a8e12016-09-01 13:03:50 -0700528 Header(const uint8_t* magic,
529 uint32_t checksum,
530 const uint8_t* signature,
531 uint32_t endian_tag,
532 uint32_t file_size,
533 uint32_t header_size,
534 uint32_t link_size,
535 uint32_t link_offset,
536 uint32_t data_size,
Mathieu Chartierf6e31472017-12-28 13:32:08 -0800537 uint32_t data_offset,
538 bool support_default_methods)
Jeff Hao3ab96b42016-09-09 18:35:01 -0700539 : Item(0, kHeaderItemSize),
540 checksum_(checksum),
David Sehr853a8e12016-09-01 13:03:50 -0700541 endian_tag_(endian_tag),
542 file_size_(file_size),
543 header_size_(header_size),
544 link_size_(link_size),
545 link_offset_(link_offset),
546 data_size_(data_size),
Mathieu Chartierf6e31472017-12-28 13:32:08 -0800547 data_offset_(data_offset),
548 support_default_methods_(support_default_methods) {
David Sehr853a8e12016-09-01 13:03:50 -0700549 memcpy(magic_, magic, sizeof(magic_));
550 memcpy(signature_, signature, sizeof(signature_));
551 }
David Sehr7629f602016-08-07 16:01:51 -0700552 ~Header() OVERRIDE { }
553
Jeff Hao3ab96b42016-09-09 18:35:01 -0700554 static size_t ItemSize() { return kHeaderItemSize; }
555
David Sehr7629f602016-08-07 16:01:51 -0700556 const uint8_t* Magic() const { return magic_; }
557 uint32_t Checksum() const { return checksum_; }
558 const uint8_t* Signature() const { return signature_; }
559 uint32_t EndianTag() const { return endian_tag_; }
560 uint32_t FileSize() const { return file_size_; }
561 uint32_t HeaderSize() const { return header_size_; }
562 uint32_t LinkSize() const { return link_size_; }
563 uint32_t LinkOffset() const { return link_offset_; }
564 uint32_t DataSize() const { return data_size_; }
565 uint32_t DataOffset() const { return data_offset_; }
566
567 void SetChecksum(uint32_t new_checksum) { checksum_ = new_checksum; }
568 void SetSignature(const uint8_t* new_signature) {
569 memcpy(signature_, new_signature, sizeof(signature_));
570 }
571 void SetFileSize(uint32_t new_file_size) { file_size_ = new_file_size; }
572 void SetHeaderSize(uint32_t new_header_size) { header_size_ = new_header_size; }
573 void SetLinkSize(uint32_t new_link_size) { link_size_ = new_link_size; }
574 void SetLinkOffset(uint32_t new_link_offset) { link_offset_ = new_link_offset; }
575 void SetDataSize(uint32_t new_data_size) { data_size_ = new_data_size; }
576 void SetDataOffset(uint32_t new_data_offset) { data_offset_ = new_data_offset; }
577
Jeff Hao3ab96b42016-09-09 18:35:01 -0700578 Collections& GetCollections() { return collections_; }
Jeff Haoc3acfc52016-08-29 14:18:26 -0700579
David Sehr7629f602016-08-07 16:01:51 -0700580 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
581
Mathieu Chartierf6e31472017-12-28 13:32:08 -0800582 bool SupportDefaultMethods() const {
583 return support_default_methods_;
584 }
585
David Sehr7629f602016-08-07 16:01:51 -0700586 private:
David Sehr7629f602016-08-07 16:01:51 -0700587 uint8_t magic_[8];
588 uint32_t checksum_;
589 uint8_t signature_[DexFile::kSha1DigestSize];
590 uint32_t endian_tag_;
591 uint32_t file_size_;
592 uint32_t header_size_;
593 uint32_t link_size_;
594 uint32_t link_offset_;
595 uint32_t data_size_;
596 uint32_t data_offset_;
Mathieu Chartierf6e31472017-12-28 13:32:08 -0800597 const bool support_default_methods_;
David Sehr7629f602016-08-07 16:01:51 -0700598
Jeff Hao3ab96b42016-09-09 18:35:01 -0700599 Collections collections_;
600
David Sehr7629f602016-08-07 16:01:51 -0700601 DISALLOW_COPY_AND_ASSIGN(Header);
602};
603
Jeff Hao3ab96b42016-09-09 18:35:01 -0700604class StringData : public Item {
David Sehr7629f602016-08-07 16:01:51 -0700605 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700606 explicit StringData(const char* data) : data_(strdup(data)) {
Jeff Haoa8621002016-10-04 18:13:44 +0000607 size_ = UnsignedLeb128Size(CountModifiedUtf8Chars(data)) + strlen(data);
Jeff Hao3ab96b42016-09-09 18:35:01 -0700608 }
David Sehr7629f602016-08-07 16:01:51 -0700609
610 const char* Data() const { return data_.get(); }
611
612 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
613
614 private:
Jeff Haoa8621002016-10-04 18:13:44 +0000615 UniqueCPtr<const char> data_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700616
617 DISALLOW_COPY_AND_ASSIGN(StringData);
618};
619
620class StringId : public IndexedItem {
621 public:
622 explicit StringId(StringData* string_data) : string_data_(string_data) {
623 size_ = kStringIdItemSize;
624 }
625 ~StringId() OVERRIDE { }
626
627 static size_t ItemSize() { return kStringIdItemSize; }
628
629 const char* Data() const { return string_data_->Data(); }
630 StringData* DataItem() const { return string_data_; }
631
632 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
633
634 private:
635 StringData* string_data_;
636
David Sehr7629f602016-08-07 16:01:51 -0700637 DISALLOW_COPY_AND_ASSIGN(StringId);
638};
639
Jeff Hao3ab96b42016-09-09 18:35:01 -0700640class TypeId : public IndexedItem {
David Sehr7629f602016-08-07 16:01:51 -0700641 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700642 explicit TypeId(StringId* string_id) : string_id_(string_id) { size_ = kTypeIdItemSize; }
David Sehr7629f602016-08-07 16:01:51 -0700643 ~TypeId() OVERRIDE { }
644
Jeff Hao3ab96b42016-09-09 18:35:01 -0700645 static size_t ItemSize() { return kTypeIdItemSize; }
646
David Sehr7629f602016-08-07 16:01:51 -0700647 StringId* GetStringId() const { return string_id_; }
648
649 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
650
651 private:
652 StringId* string_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700653
David Sehr7629f602016-08-07 16:01:51 -0700654 DISALLOW_COPY_AND_ASSIGN(TypeId);
655};
656
David Sehr853a8e12016-09-01 13:03:50 -0700657using TypeIdVector = std::vector<const TypeId*>;
658
Jeff Hao3ab96b42016-09-09 18:35:01 -0700659class TypeList : public Item {
David Sehr7629f602016-08-07 16:01:51 -0700660 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700661 explicit TypeList(TypeIdVector* type_list) : type_list_(type_list) {
662 size_ = sizeof(uint32_t) + (type_list->size() * sizeof(uint16_t));
663 }
664 ~TypeList() OVERRIDE { }
665
666 const TypeIdVector* GetTypeList() const { return type_list_.get(); }
667
668 private:
669 std::unique_ptr<TypeIdVector> type_list_;
670
671 DISALLOW_COPY_AND_ASSIGN(TypeList);
672};
673
674class ProtoId : public IndexedItem {
675 public:
676 ProtoId(const StringId* shorty, const TypeId* return_type, TypeList* parameters)
677 : shorty_(shorty), return_type_(return_type), parameters_(parameters)
678 { size_ = kProtoIdItemSize; }
David Sehr7629f602016-08-07 16:01:51 -0700679 ~ProtoId() OVERRIDE { }
680
Jeff Hao3ab96b42016-09-09 18:35:01 -0700681 static size_t ItemSize() { return kProtoIdItemSize; }
682
David Sehr7629f602016-08-07 16:01:51 -0700683 const StringId* Shorty() const { return shorty_; }
684 const TypeId* ReturnType() const { return return_type_; }
Jeff Haoa8621002016-10-04 18:13:44 +0000685 const TypeList* Parameters() const { return parameters_; }
David Sehr7629f602016-08-07 16:01:51 -0700686
687 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
688
689 private:
690 const StringId* shorty_;
691 const TypeId* return_type_;
Jeff Haoa8621002016-10-04 18:13:44 +0000692 TypeList* parameters_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -0700693
David Sehr7629f602016-08-07 16:01:51 -0700694 DISALLOW_COPY_AND_ASSIGN(ProtoId);
695};
696
Jeff Hao3ab96b42016-09-09 18:35:01 -0700697class FieldId : public IndexedItem {
David Sehr7629f602016-08-07 16:01:51 -0700698 public:
David Sehr853a8e12016-09-01 13:03:50 -0700699 FieldId(const TypeId* klass, const TypeId* type, const StringId* name)
Jeff Hao3ab96b42016-09-09 18:35:01 -0700700 : class_(klass), type_(type), name_(name) { size_ = kFieldIdItemSize; }
David Sehr7629f602016-08-07 16:01:51 -0700701 ~FieldId() OVERRIDE { }
702
Jeff Hao3ab96b42016-09-09 18:35:01 -0700703 static size_t ItemSize() { return kFieldIdItemSize; }
704
David Sehr7629f602016-08-07 16:01:51 -0700705 const TypeId* Class() const { return class_; }
706 const TypeId* Type() const { return type_; }
707 const StringId* Name() const { return name_; }
708
709 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
710
711 private:
712 const TypeId* class_;
713 const TypeId* type_;
714 const StringId* name_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700715
David Sehr7629f602016-08-07 16:01:51 -0700716 DISALLOW_COPY_AND_ASSIGN(FieldId);
717};
718
Jeff Hao3ab96b42016-09-09 18:35:01 -0700719class MethodId : public IndexedItem {
David Sehr7629f602016-08-07 16:01:51 -0700720 public:
David Sehr853a8e12016-09-01 13:03:50 -0700721 MethodId(const TypeId* klass, const ProtoId* proto, const StringId* name)
Jeff Hao3ab96b42016-09-09 18:35:01 -0700722 : class_(klass), proto_(proto), name_(name) { size_ = kMethodIdItemSize; }
David Sehr7629f602016-08-07 16:01:51 -0700723 ~MethodId() OVERRIDE { }
724
Jeff Hao3ab96b42016-09-09 18:35:01 -0700725 static size_t ItemSize() { return kMethodIdItemSize; }
726
David Sehr7629f602016-08-07 16:01:51 -0700727 const TypeId* Class() const { return class_; }
728 const ProtoId* Proto() const { return proto_; }
729 const StringId* Name() const { return name_; }
730
731 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
732
733 private:
734 const TypeId* class_;
735 const ProtoId* proto_;
736 const StringId* name_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700737
David Sehr7629f602016-08-07 16:01:51 -0700738 DISALLOW_COPY_AND_ASSIGN(MethodId);
739};
740
741class FieldItem : public Item {
742 public:
David Sehr853a8e12016-09-01 13:03:50 -0700743 FieldItem(uint32_t access_flags, const FieldId* field_id)
744 : access_flags_(access_flags), field_id_(field_id) { }
David Sehr7629f602016-08-07 16:01:51 -0700745 ~FieldItem() OVERRIDE { }
746
747 uint32_t GetAccessFlags() const { return access_flags_; }
748 const FieldId* GetFieldId() const { return field_id_; }
749
750 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
751
752 private:
753 uint32_t access_flags_;
754 const FieldId* field_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700755
David Sehr7629f602016-08-07 16:01:51 -0700756 DISALLOW_COPY_AND_ASSIGN(FieldItem);
757};
758
David Sehr853a8e12016-09-01 13:03:50 -0700759using FieldItemVector = std::vector<std::unique_ptr<FieldItem>>;
760
David Sehr7629f602016-08-07 16:01:51 -0700761class MethodItem : public Item {
762 public:
Jeff Haoea7c6292016-11-14 18:10:16 -0800763 MethodItem(uint32_t access_flags, const MethodId* method_id, CodeItem* code)
David Sehr853a8e12016-09-01 13:03:50 -0700764 : access_flags_(access_flags), method_id_(method_id), code_(code) { }
David Sehr7629f602016-08-07 16:01:51 -0700765 ~MethodItem() OVERRIDE { }
766
767 uint32_t GetAccessFlags() const { return access_flags_; }
768 const MethodId* GetMethodId() const { return method_id_; }
Jeff Haoea7c6292016-11-14 18:10:16 -0800769 CodeItem* GetCodeItem() { return code_; }
David Sehr7629f602016-08-07 16:01:51 -0700770
771 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
772
773 private:
774 uint32_t access_flags_;
775 const MethodId* method_id_;
Jeff Haoea7c6292016-11-14 18:10:16 -0800776 CodeItem* code_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -0700777
David Sehr7629f602016-08-07 16:01:51 -0700778 DISALLOW_COPY_AND_ASSIGN(MethodItem);
779};
780
David Sehr853a8e12016-09-01 13:03:50 -0700781using MethodItemVector = std::vector<std::unique_ptr<MethodItem>>;
782
Jeff Hao3ab96b42016-09-09 18:35:01 -0700783class EncodedValue {
David Sehr7629f602016-08-07 16:01:51 -0700784 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -0700785 explicit EncodedValue(uint8_t type) : type_(type) { }
David Sehr7629f602016-08-07 16:01:51 -0700786
787 int8_t Type() const { return type_; }
David Sehr7629f602016-08-07 16:01:51 -0700788
Jeff Hao3ab96b42016-09-09 18:35:01 -0700789 void SetBoolean(bool z) { u_.bool_val_ = z; }
790 void SetByte(int8_t b) { u_.byte_val_ = b; }
791 void SetShort(int16_t s) { u_.short_val_ = s; }
792 void SetChar(uint16_t c) { u_.char_val_ = c; }
793 void SetInt(int32_t i) { u_.int_val_ = i; }
794 void SetLong(int64_t l) { u_.long_val_ = l; }
795 void SetFloat(float f) { u_.float_val_ = f; }
796 void SetDouble(double d) { u_.double_val_ = d; }
797 void SetStringId(StringId* string_id) { u_.string_val_ = string_id; }
798 void SetTypeId(TypeId* type_id) { u_.type_val_ = type_id; }
Jeff Hao5daee902017-04-27 18:00:38 -0700799 void SetProtoId(ProtoId* proto_id) { u_.proto_val_ = proto_id; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700800 void SetFieldId(FieldId* field_id) { u_.field_val_ = field_id; }
801 void SetMethodId(MethodId* method_id) { u_.method_val_ = method_id; }
Jeff Hao5daee902017-04-27 18:00:38 -0700802 void SetMethodHandle(MethodHandleItem* method_handle) { u_.method_handle_val_ = method_handle; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700803 void SetEncodedArray(EncodedArrayItem* encoded_array) { encoded_array_.reset(encoded_array); }
804 void SetEncodedAnnotation(EncodedAnnotation* encoded_annotation)
805 { encoded_annotation_.reset(encoded_annotation); }
806
807 bool GetBoolean() const { return u_.bool_val_; }
808 int8_t GetByte() const { return u_.byte_val_; }
809 int16_t GetShort() const { return u_.short_val_; }
810 uint16_t GetChar() const { return u_.char_val_; }
811 int32_t GetInt() const { return u_.int_val_; }
812 int64_t GetLong() const { return u_.long_val_; }
813 float GetFloat() const { return u_.float_val_; }
814 double GetDouble() const { return u_.double_val_; }
815 StringId* GetStringId() const { return u_.string_val_; }
816 TypeId* GetTypeId() const { return u_.type_val_; }
Jeff Hao5daee902017-04-27 18:00:38 -0700817 ProtoId* GetProtoId() const { return u_.proto_val_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700818 FieldId* GetFieldId() const { return u_.field_val_; }
819 MethodId* GetMethodId() const { return u_.method_val_; }
Jeff Hao5daee902017-04-27 18:00:38 -0700820 MethodHandleItem* GetMethodHandle() const { return u_.method_handle_val_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700821 EncodedArrayItem* GetEncodedArray() const { return encoded_array_.get(); }
822 EncodedAnnotation* GetEncodedAnnotation() const { return encoded_annotation_.get(); }
823
824 EncodedAnnotation* ReleaseEncodedAnnotation() { return encoded_annotation_.release(); }
David Sehr7629f602016-08-07 16:01:51 -0700825
826 private:
David Sehr7629f602016-08-07 16:01:51 -0700827 uint8_t type_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700828 union {
829 bool bool_val_;
830 int8_t byte_val_;
831 int16_t short_val_;
832 uint16_t char_val_;
833 int32_t int_val_;
834 int64_t long_val_;
835 float float_val_;
836 double double_val_;
837 StringId* string_val_;
838 TypeId* type_val_;
Jeff Hao5daee902017-04-27 18:00:38 -0700839 ProtoId* proto_val_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700840 FieldId* field_val_;
841 MethodId* method_val_;
Jeff Hao5daee902017-04-27 18:00:38 -0700842 MethodHandleItem* method_handle_val_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700843 } u_;
844 std::unique_ptr<EncodedArrayItem> encoded_array_;
845 std::unique_ptr<EncodedAnnotation> encoded_annotation_;
846
847 DISALLOW_COPY_AND_ASSIGN(EncodedValue);
David Sehr7629f602016-08-07 16:01:51 -0700848};
849
Jeff Hao3ab96b42016-09-09 18:35:01 -0700850using EncodedValueVector = std::vector<std::unique_ptr<EncodedValue>>;
851
852class AnnotationElement {
853 public:
854 AnnotationElement(StringId* name, EncodedValue* value) : name_(name), value_(value) { }
855
856 StringId* GetName() const { return name_; }
857 EncodedValue* GetValue() const { return value_.get(); }
858
859 private:
860 StringId* name_;
861 std::unique_ptr<EncodedValue> value_;
862
863 DISALLOW_COPY_AND_ASSIGN(AnnotationElement);
864};
865
866using AnnotationElementVector = std::vector<std::unique_ptr<AnnotationElement>>;
867
868class EncodedAnnotation {
869 public:
870 EncodedAnnotation(TypeId* type, AnnotationElementVector* elements)
871 : type_(type), elements_(elements) { }
872
873 TypeId* GetType() const { return type_; }
874 AnnotationElementVector* GetAnnotationElements() const { return elements_.get(); }
875
876 private:
877 TypeId* type_;
878 std::unique_ptr<AnnotationElementVector> elements_;
879
880 DISALLOW_COPY_AND_ASSIGN(EncodedAnnotation);
881};
882
883class EncodedArrayItem : public Item {
884 public:
885 explicit EncodedArrayItem(EncodedValueVector* encoded_values)
886 : encoded_values_(encoded_values) { }
887
888 EncodedValueVector* GetEncodedValues() const { return encoded_values_.get(); }
889
890 private:
891 std::unique_ptr<EncodedValueVector> encoded_values_;
892
893 DISALLOW_COPY_AND_ASSIGN(EncodedArrayItem);
894};
David Sehr853a8e12016-09-01 13:03:50 -0700895
David Sehr7629f602016-08-07 16:01:51 -0700896class ClassData : public Item {
897 public:
David Sehr853a8e12016-09-01 13:03:50 -0700898 ClassData(FieldItemVector* static_fields,
899 FieldItemVector* instance_fields,
900 MethodItemVector* direct_methods,
901 MethodItemVector* virtual_methods)
902 : static_fields_(static_fields),
903 instance_fields_(instance_fields),
904 direct_methods_(direct_methods),
905 virtual_methods_(virtual_methods) { }
906
David Sehr7629f602016-08-07 16:01:51 -0700907 ~ClassData() OVERRIDE = default;
David Sehr853a8e12016-09-01 13:03:50 -0700908 FieldItemVector* StaticFields() { return static_fields_.get(); }
909 FieldItemVector* InstanceFields() { return instance_fields_.get(); }
910 MethodItemVector* DirectMethods() { return direct_methods_.get(); }
911 MethodItemVector* VirtualMethods() { return virtual_methods_.get(); }
David Sehr7629f602016-08-07 16:01:51 -0700912
913 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
914
915 private:
David Sehr853a8e12016-09-01 13:03:50 -0700916 std::unique_ptr<FieldItemVector> static_fields_;
917 std::unique_ptr<FieldItemVector> instance_fields_;
918 std::unique_ptr<MethodItemVector> direct_methods_;
919 std::unique_ptr<MethodItemVector> virtual_methods_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700920
David Sehr7629f602016-08-07 16:01:51 -0700921 DISALLOW_COPY_AND_ASSIGN(ClassData);
922};
923
Jeff Hao3ab96b42016-09-09 18:35:01 -0700924class ClassDef : public IndexedItem {
David Sehr7629f602016-08-07 16:01:51 -0700925 public:
David Sehr853a8e12016-09-01 13:03:50 -0700926 ClassDef(const TypeId* class_type,
927 uint32_t access_flags,
928 const TypeId* superclass,
Jeff Hao3ab96b42016-09-09 18:35:01 -0700929 TypeList* interfaces,
David Sehr853a8e12016-09-01 13:03:50 -0700930 const StringId* source_file,
931 AnnotationsDirectoryItem* annotations,
Jeff Hao3ab96b42016-09-09 18:35:01 -0700932 EncodedArrayItem* static_values,
David Sehr853a8e12016-09-01 13:03:50 -0700933 ClassData* class_data)
934 : class_type_(class_type),
935 access_flags_(access_flags),
936 superclass_(superclass),
937 interfaces_(interfaces),
David Sehr853a8e12016-09-01 13:03:50 -0700938 source_file_(source_file),
939 annotations_(annotations),
Jeff Haoa8621002016-10-04 18:13:44 +0000940 class_data_(class_data),
941 static_values_(static_values) { size_ = kClassDefItemSize; }
David Sehr853a8e12016-09-01 13:03:50 -0700942
David Sehr7629f602016-08-07 16:01:51 -0700943 ~ClassDef() OVERRIDE { }
944
Jeff Hao3ab96b42016-09-09 18:35:01 -0700945 static size_t ItemSize() { return kClassDefItemSize; }
946
David Sehr7629f602016-08-07 16:01:51 -0700947 const TypeId* ClassType() const { return class_type_; }
948 uint32_t GetAccessFlags() const { return access_flags_; }
949 const TypeId* Superclass() const { return superclass_; }
Jeff Haocc829592017-03-14 16:13:39 -0700950 const TypeList* Interfaces() { return interfaces_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700951 uint32_t InterfacesOffset() { return interfaces_ == nullptr ? 0 : interfaces_->GetOffset(); }
David Sehr7629f602016-08-07 16:01:51 -0700952 const StringId* SourceFile() const { return source_file_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -0700953 AnnotationsDirectoryItem* Annotations() const { return annotations_; }
Nicolas Geoffrayfd1a6c22016-10-04 11:01:17 +0000954 ClassData* GetClassData() { return class_data_; }
Jeff Haoa8621002016-10-04 18:13:44 +0000955 EncodedArrayItem* StaticValues() { return static_values_; }
David Sehr7629f602016-08-07 16:01:51 -0700956
Jeff Haoc3acfc52016-08-29 14:18:26 -0700957 MethodItem* GenerateMethodItem(Header& header, ClassDataItemIterator& cdii);
958
David Sehr7629f602016-08-07 16:01:51 -0700959 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
960
961 private:
962 const TypeId* class_type_;
963 uint32_t access_flags_;
Jeff Haoa8621002016-10-04 18:13:44 +0000964 const TypeId* superclass_; // This can be nullptr.
965 TypeList* interfaces_; // This can be nullptr.
966 const StringId* source_file_; // This can be nullptr.
967 AnnotationsDirectoryItem* annotations_; // This can be nullptr.
968 ClassData* class_data_; // This can be nullptr.
969 EncodedArrayItem* static_values_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -0700970
David Sehr7629f602016-08-07 16:01:51 -0700971 DISALLOW_COPY_AND_ASSIGN(ClassDef);
972};
973
Jeff Haoa8621002016-10-04 18:13:44 +0000974class TypeAddrPair {
David Sehr853a8e12016-09-01 13:03:50 -0700975 public:
Jeff Haoa8621002016-10-04 18:13:44 +0000976 TypeAddrPair(const TypeId* type_id, uint32_t address) : type_id_(type_id), address_(address) { }
David Sehr853a8e12016-09-01 13:03:50 -0700977
978 const TypeId* GetTypeId() const { return type_id_; }
979 uint32_t GetAddress() const { return address_; }
980
981 private:
Jeff Haocc829592017-03-14 16:13:39 -0700982 const TypeId* type_id_; // This can be nullptr.
David Sehr853a8e12016-09-01 13:03:50 -0700983 uint32_t address_;
Jeff Hao3ab96b42016-09-09 18:35:01 -0700984
Jeff Haoa8621002016-10-04 18:13:44 +0000985 DISALLOW_COPY_AND_ASSIGN(TypeAddrPair);
986};
987
988using TypeAddrPairVector = std::vector<std::unique_ptr<const TypeAddrPair>>;
989
990class CatchHandler {
991 public:
992 explicit CatchHandler(bool catch_all, uint16_t list_offset, TypeAddrPairVector* handlers)
993 : catch_all_(catch_all), list_offset_(list_offset), handlers_(handlers) { }
994
995 bool HasCatchAll() const { return catch_all_; }
996 uint16_t GetListOffset() const { return list_offset_; }
997 TypeAddrPairVector* GetHandlers() const { return handlers_.get(); }
998
999 private:
1000 bool catch_all_;
1001 uint16_t list_offset_;
1002 std::unique_ptr<TypeAddrPairVector> handlers_;
1003
David Sehr853a8e12016-09-01 13:03:50 -07001004 DISALLOW_COPY_AND_ASSIGN(CatchHandler);
1005};
1006
1007using CatchHandlerVector = std::vector<std::unique_ptr<const CatchHandler>>;
1008
1009class TryItem : public Item {
1010 public:
Jeff Haoa8621002016-10-04 18:13:44 +00001011 TryItem(uint32_t start_addr, uint16_t insn_count, const CatchHandler* handlers)
David Sehr853a8e12016-09-01 13:03:50 -07001012 : start_addr_(start_addr), insn_count_(insn_count), handlers_(handlers) { }
1013 ~TryItem() OVERRIDE { }
1014
1015 uint32_t StartAddr() const { return start_addr_; }
1016 uint16_t InsnCount() const { return insn_count_; }
Jeff Haoa8621002016-10-04 18:13:44 +00001017 const CatchHandler* GetHandlers() const { return handlers_; }
David Sehr853a8e12016-09-01 13:03:50 -07001018
1019 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1020
1021 private:
1022 uint32_t start_addr_;
1023 uint16_t insn_count_;
Jeff Haoa8621002016-10-04 18:13:44 +00001024 const CatchHandler* handlers_;
Jeff Hao3ab96b42016-09-09 18:35:01 -07001025
David Sehr853a8e12016-09-01 13:03:50 -07001026 DISALLOW_COPY_AND_ASSIGN(TryItem);
1027};
1028
1029using TryItemVector = std::vector<std::unique_ptr<const TryItem>>;
1030
David Sehrd1e44e22016-10-06 17:09:32 -07001031class CodeFixups {
1032 public:
Vladimir Marko219cb902017-12-07 16:20:39 +00001033 CodeFixups(std::vector<TypeId*> type_ids,
1034 std::vector<StringId*> string_ids,
1035 std::vector<MethodId*> method_ids,
1036 std::vector<FieldId*> field_ids)
1037 : type_ids_(std::move(type_ids)),
1038 string_ids_(std::move(string_ids)),
1039 method_ids_(std::move(method_ids)),
1040 field_ids_(std::move(field_ids)) { }
David Sehrd1e44e22016-10-06 17:09:32 -07001041
Vladimir Marko219cb902017-12-07 16:20:39 +00001042 const std::vector<TypeId*>& TypeIds() const { return type_ids_; }
1043 const std::vector<StringId*>& StringIds() const { return string_ids_; }
1044 const std::vector<MethodId*>& MethodIds() const { return method_ids_; }
1045 const std::vector<FieldId*>& FieldIds() const { return field_ids_; }
David Sehrd1e44e22016-10-06 17:09:32 -07001046
1047 private:
Vladimir Marko219cb902017-12-07 16:20:39 +00001048 std::vector<TypeId*> type_ids_;
1049 std::vector<StringId*> string_ids_;
1050 std::vector<MethodId*> method_ids_;
1051 std::vector<FieldId*> field_ids_;
David Sehrd1e44e22016-10-06 17:09:32 -07001052
1053 DISALLOW_COPY_AND_ASSIGN(CodeFixups);
1054};
1055
David Sehr7629f602016-08-07 16:01:51 -07001056class CodeItem : public Item {
1057 public:
David Sehr853a8e12016-09-01 13:03:50 -07001058 CodeItem(uint16_t registers_size,
1059 uint16_t ins_size,
1060 uint16_t outs_size,
1061 DebugInfoItem* debug_info,
1062 uint32_t insns_size,
1063 uint16_t* insns,
Jeff Haoa8621002016-10-04 18:13:44 +00001064 TryItemVector* tries,
1065 CatchHandlerVector* handlers)
David Sehr853a8e12016-09-01 13:03:50 -07001066 : registers_size_(registers_size),
1067 ins_size_(ins_size),
1068 outs_size_(outs_size),
1069 debug_info_(debug_info),
1070 insns_size_(insns_size),
1071 insns_(insns),
Jeff Haoa8621002016-10-04 18:13:44 +00001072 tries_(tries),
1073 handlers_(handlers) { }
David Sehr853a8e12016-09-01 13:03:50 -07001074
David Sehr7629f602016-08-07 16:01:51 -07001075 ~CodeItem() OVERRIDE { }
1076
1077 uint16_t RegistersSize() const { return registers_size_; }
1078 uint16_t InsSize() const { return ins_size_; }
1079 uint16_t OutsSize() const { return outs_size_; }
David Sehr853a8e12016-09-01 13:03:50 -07001080 uint16_t TriesSize() const { return tries_ == nullptr ? 0 : tries_->size(); }
Jeff Hao3ab96b42016-09-09 18:35:01 -07001081 DebugInfoItem* DebugInfo() const { return debug_info_; }
David Sehr7629f602016-08-07 16:01:51 -07001082 uint32_t InsnsSize() const { return insns_size_; }
1083 uint16_t* Insns() const { return insns_.get(); }
David Sehr853a8e12016-09-01 13:03:50 -07001084 TryItemVector* Tries() const { return tries_.get(); }
Jeff Haoa8621002016-10-04 18:13:44 +00001085 CatchHandlerVector* Handlers() const { return handlers_.get(); }
David Sehr7629f602016-08-07 16:01:51 -07001086
David Sehrd1e44e22016-10-06 17:09:32 -07001087 void SetCodeFixups(CodeFixups* fixups) { fixups_.reset(fixups); }
1088 CodeFixups* GetCodeFixups() const { return fixups_.get(); }
1089
David Sehr7629f602016-08-07 16:01:51 -07001090 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1091
Mathieu Chartier1d2d4ff2017-09-23 16:11:06 -07001092 IterationRange<DexInstructionIterator> Instructions() const {
Mathieu Chartier2b2bef22017-10-26 17:10:19 -07001093 return MakeIterationRange(DexInstructionIterator(Insns(), 0u),
1094 DexInstructionIterator(Insns(), InsnsSize()));
Mathieu Chartier1d2d4ff2017-09-23 16:11:06 -07001095 }
1096
David Sehr7629f602016-08-07 16:01:51 -07001097 private:
1098 uint16_t registers_size_;
1099 uint16_t ins_size_;
1100 uint16_t outs_size_;
Jeff Haoa8621002016-10-04 18:13:44 +00001101 DebugInfoItem* debug_info_; // This can be nullptr.
David Sehr7629f602016-08-07 16:01:51 -07001102 uint32_t insns_size_;
1103 std::unique_ptr<uint16_t[]> insns_;
Jeff Haoa8621002016-10-04 18:13:44 +00001104 std::unique_ptr<TryItemVector> tries_; // This can be nullptr.
1105 std::unique_ptr<CatchHandlerVector> handlers_; // This can be nullptr.
David Sehrd1e44e22016-10-06 17:09:32 -07001106 std::unique_ptr<CodeFixups> fixups_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -07001107
David Sehr7629f602016-08-07 16:01:51 -07001108 DISALLOW_COPY_AND_ASSIGN(CodeItem);
1109};
1110
David Sehr7629f602016-08-07 16:01:51 -07001111class DebugInfoItem : public Item {
1112 public:
Jeff Haoa8621002016-10-04 18:13:44 +00001113 DebugInfoItem(uint32_t debug_info_size, uint8_t* debug_info)
1114 : debug_info_size_(debug_info_size), debug_info_(debug_info) { }
1115
1116 uint32_t GetDebugInfoSize() const { return debug_info_size_; }
1117 uint8_t* GetDebugInfo() const { return debug_info_.get(); }
David Sehr7629f602016-08-07 16:01:51 -07001118
David Sehr7629f602016-08-07 16:01:51 -07001119 private:
Jeff Haoa8621002016-10-04 18:13:44 +00001120 uint32_t debug_info_size_;
1121 std::unique_ptr<uint8_t[]> debug_info_;
1122
David Sehr7629f602016-08-07 16:01:51 -07001123 DISALLOW_COPY_AND_ASSIGN(DebugInfoItem);
1124};
1125
Jeff Hao3ab96b42016-09-09 18:35:01 -07001126class AnnotationItem : public Item {
David Sehr853a8e12016-09-01 13:03:50 -07001127 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -07001128 AnnotationItem(uint8_t visibility, EncodedAnnotation* annotation)
1129 : visibility_(visibility), annotation_(annotation) { }
David Sehr853a8e12016-09-01 13:03:50 -07001130
1131 uint8_t GetVisibility() const { return visibility_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -07001132 EncodedAnnotation* GetAnnotation() const { return annotation_.get(); }
David Sehr7629f602016-08-07 16:01:51 -07001133
1134 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1135
1136 private:
Jeff Hao3ab96b42016-09-09 18:35:01 -07001137 uint8_t visibility_;
1138 std::unique_ptr<EncodedAnnotation> annotation_;
1139
1140 DISALLOW_COPY_AND_ASSIGN(AnnotationItem);
1141};
1142
1143class AnnotationSetItem : public Item {
1144 public:
1145 explicit AnnotationSetItem(std::vector<AnnotationItem*>* items) : items_(items) {
1146 size_ = sizeof(uint32_t) + items->size() * sizeof(uint32_t);
1147 }
1148 ~AnnotationSetItem() OVERRIDE { }
1149
1150 std::vector<AnnotationItem*>* GetItems() { return items_.get(); }
1151
1152 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1153
1154 private:
1155 std::unique_ptr<std::vector<AnnotationItem*>> items_;
1156
David Sehr7629f602016-08-07 16:01:51 -07001157 DISALLOW_COPY_AND_ASSIGN(AnnotationSetItem);
1158};
1159
Jeff Hao3ab96b42016-09-09 18:35:01 -07001160class AnnotationSetRefList : public Item {
1161 public:
1162 explicit AnnotationSetRefList(std::vector<AnnotationSetItem*>* items) : items_(items) {
1163 size_ = sizeof(uint32_t) + items->size() * sizeof(uint32_t);
1164 }
1165 ~AnnotationSetRefList() OVERRIDE { }
1166
1167 std::vector<AnnotationSetItem*>* GetItems() { return items_.get(); }
1168
1169 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1170
1171 private:
Jeff Haoa8621002016-10-04 18:13:44 +00001172 std::unique_ptr<std::vector<AnnotationSetItem*>> items_; // Elements of vector can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -07001173
1174 DISALLOW_COPY_AND_ASSIGN(AnnotationSetRefList);
1175};
David Sehr853a8e12016-09-01 13:03:50 -07001176
1177class FieldAnnotation {
1178 public:
1179 FieldAnnotation(FieldId* field_id, AnnotationSetItem* annotation_set_item)
1180 : field_id_(field_id), annotation_set_item_(annotation_set_item) { }
1181
1182 FieldId* GetFieldId() const { return field_id_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -07001183 AnnotationSetItem* GetAnnotationSetItem() const { return annotation_set_item_; }
David Sehr853a8e12016-09-01 13:03:50 -07001184
1185 private:
1186 FieldId* field_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -07001187 AnnotationSetItem* annotation_set_item_;
1188
David Sehr853a8e12016-09-01 13:03:50 -07001189 DISALLOW_COPY_AND_ASSIGN(FieldAnnotation);
1190};
1191
1192using FieldAnnotationVector = std::vector<std::unique_ptr<FieldAnnotation>>;
1193
1194class MethodAnnotation {
1195 public:
1196 MethodAnnotation(MethodId* method_id, AnnotationSetItem* annotation_set_item)
1197 : method_id_(method_id), annotation_set_item_(annotation_set_item) { }
1198
1199 MethodId* GetMethodId() const { return method_id_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -07001200 AnnotationSetItem* GetAnnotationSetItem() const { return annotation_set_item_; }
David Sehr853a8e12016-09-01 13:03:50 -07001201
1202 private:
1203 MethodId* method_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -07001204 AnnotationSetItem* annotation_set_item_;
1205
David Sehr853a8e12016-09-01 13:03:50 -07001206 DISALLOW_COPY_AND_ASSIGN(MethodAnnotation);
1207};
1208
1209using MethodAnnotationVector = std::vector<std::unique_ptr<MethodAnnotation>>;
1210
1211class ParameterAnnotation {
1212 public:
Jeff Hao3ab96b42016-09-09 18:35:01 -07001213 ParameterAnnotation(MethodId* method_id, AnnotationSetRefList* annotations)
David Sehr853a8e12016-09-01 13:03:50 -07001214 : method_id_(method_id), annotations_(annotations) { }
1215
1216 MethodId* GetMethodId() const { return method_id_; }
Jeff Hao3ab96b42016-09-09 18:35:01 -07001217 AnnotationSetRefList* GetAnnotations() { return annotations_; }
David Sehr853a8e12016-09-01 13:03:50 -07001218
1219 private:
1220 MethodId* method_id_;
Jeff Hao3ab96b42016-09-09 18:35:01 -07001221 AnnotationSetRefList* annotations_;
1222
David Sehr853a8e12016-09-01 13:03:50 -07001223 DISALLOW_COPY_AND_ASSIGN(ParameterAnnotation);
1224};
1225
1226using ParameterAnnotationVector = std::vector<std::unique_ptr<ParameterAnnotation>>;
1227
David Sehr7629f602016-08-07 16:01:51 -07001228class AnnotationsDirectoryItem : public Item {
1229 public:
David Sehr853a8e12016-09-01 13:03:50 -07001230 AnnotationsDirectoryItem(AnnotationSetItem* class_annotation,
1231 FieldAnnotationVector* field_annotations,
1232 MethodAnnotationVector* method_annotations,
1233 ParameterAnnotationVector* parameter_annotations)
1234 : class_annotation_(class_annotation),
1235 field_annotations_(field_annotations),
1236 method_annotations_(method_annotations),
1237 parameter_annotations_(parameter_annotations) { }
David Sehr7629f602016-08-07 16:01:51 -07001238
Jeff Hao3ab96b42016-09-09 18:35:01 -07001239 AnnotationSetItem* GetClassAnnotation() const { return class_annotation_; }
David Sehr853a8e12016-09-01 13:03:50 -07001240 FieldAnnotationVector* GetFieldAnnotations() { return field_annotations_.get(); }
1241 MethodAnnotationVector* GetMethodAnnotations() { return method_annotations_.get(); }
1242 ParameterAnnotationVector* GetParameterAnnotations() { return parameter_annotations_.get(); }
David Sehr7629f602016-08-07 16:01:51 -07001243
1244 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1245
1246 private:
Jeff Haoa8621002016-10-04 18:13:44 +00001247 AnnotationSetItem* class_annotation_; // This can be nullptr.
1248 std::unique_ptr<FieldAnnotationVector> field_annotations_; // This can be nullptr.
1249 std::unique_ptr<MethodAnnotationVector> method_annotations_; // This can be nullptr.
1250 std::unique_ptr<ParameterAnnotationVector> parameter_annotations_; // This can be nullptr.
Jeff Hao3ab96b42016-09-09 18:35:01 -07001251
David Sehr7629f602016-08-07 16:01:51 -07001252 DISALLOW_COPY_AND_ASSIGN(AnnotationsDirectoryItem);
1253};
1254
Jeff Hao5daee902017-04-27 18:00:38 -07001255class CallSiteId : public IndexedItem {
1256 public:
1257 explicit CallSiteId(EncodedArrayItem* call_site_item) : call_site_item_(call_site_item) {
1258 size_ = kCallSiteIdItemSize;
1259 }
1260 ~CallSiteId() OVERRIDE { }
1261
1262 static size_t ItemSize() { return kCallSiteIdItemSize; }
1263
1264 EncodedArrayItem* CallSiteItem() const { return call_site_item_; }
1265
1266 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
1267
1268 private:
1269 EncodedArrayItem* call_site_item_;
1270
1271 DISALLOW_COPY_AND_ASSIGN(CallSiteId);
1272};
1273
1274class MethodHandleItem : public IndexedItem {
1275 public:
1276 MethodHandleItem(DexFile::MethodHandleType method_handle_type, IndexedItem* field_or_method_id)
1277 : method_handle_type_(method_handle_type),
1278 field_or_method_id_(field_or_method_id) {
1279 size_ = kMethodHandleItemSize;
1280 }
1281 ~MethodHandleItem() OVERRIDE { }
1282
1283 static size_t ItemSize() { return kMethodHandleItemSize; }
1284
1285 DexFile::MethodHandleType GetMethodHandleType() const { return method_handle_type_; }
1286 IndexedItem* GetFieldOrMethodId() const { return field_or_method_id_; }
1287
1288 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
1289
1290 private:
1291 DexFile::MethodHandleType method_handle_type_;
1292 IndexedItem* field_or_method_id_;
1293
1294 DISALLOW_COPY_AND_ASSIGN(MethodHandleItem);
1295};
1296
David Sehr7629f602016-08-07 16:01:51 -07001297// TODO(sehr): implement MapList.
1298class MapList : public Item {
1299 public:
1300 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1301
1302 private:
1303 DISALLOW_COPY_AND_ASSIGN(MapList);
1304};
1305
1306class MapItem : public Item {
1307 public:
1308 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
1309
1310 private:
1311 DISALLOW_COPY_AND_ASSIGN(MapItem);
1312};
1313
David Sehr9037a3a2017-03-30 17:50:24 -07001314// Interface for building a vector of file sections for use by other clients.
1315struct DexFileSection {
1316 public:
1317 DexFileSection(const std::string& name, uint16_t type, uint32_t size, uint32_t offset)
1318 : name(name), type(type), size(size), offset(offset) { }
1319 std::string name;
1320 // The type (DexFile::MapItemType).
1321 uint16_t type;
1322 // The size (in elements, not bytes).
1323 uint32_t size;
1324 // The byte offset from the start of the file.
1325 uint32_t offset;
1326};
1327
1328enum class SortDirection {
1329 kSortAscending,
1330 kSortDescending
1331};
1332
1333std::vector<DexFileSection> GetSortedDexFileSections(dex_ir::Header* header,
1334 SortDirection direction);
1335
David Sehr7629f602016-08-07 16:01:51 -07001336} // namespace dex_ir
1337} // namespace art
1338
1339#endif // ART_DEXLAYOUT_DEX_IR_H_