summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author David Sehr <sehr@google.com> 2018-06-11 14:06:23 -0700
committer David Sehr <sehr@google.com> 2018-06-13 11:08:05 -0700
commitd83437cba0eaac9797def3c09f7812e25fdcd6ac (patch)
treee29156febe965efb57099b232d9b85342db39a41
parenta316f9129a698ccb995b035f8781f93c58981893 (diff)
Use factory pattern for dex_ir objects
In preparation for memory improvements, make dex_ir API more friendly to pre-allocated or in-place type allocation. Bug: 33017139 Test: make -j 50 test-art-host Change-Id: I09b67e279a04535b175433287ce98ecbdc37f7a3
-rw-r--r--dexlayout/compact_dex_writer.cc12
-rw-r--r--dexlayout/dex_ir.cc180
-rw-r--r--dexlayout/dex_ir.h193
-rw-r--r--dexlayout/dex_ir_builder.cc9
-rw-r--r--dexlayout/dex_verify.cc8
-rw-r--r--dexlayout/dex_visualize.cc8
-rw-r--r--dexlayout/dex_writer.cc14
-rw-r--r--dexlayout/dexlayout.cc36
8 files changed, 303 insertions, 157 deletions
diff --git a/dexlayout/compact_dex_writer.cc b/dexlayout/compact_dex_writer.cc
index 2b4144c611..3f5dbcfce5 100644
--- a/dexlayout/compact_dex_writer.cc
+++ b/dexlayout/compact_dex_writer.cc
@@ -59,8 +59,8 @@ uint32_t CompactDexWriter::WriteDebugInfoOffsetTable(Stream* stream) {
for (auto& method : *(invoke_type == InvokeType::kDirect
? class_data->DirectMethods()
: class_data->VirtualMethods())) {
- const dex_ir::MethodId* method_id = method->GetMethodId();
- dex_ir::CodeItem* code_item = method->GetCodeItem();
+ const dex_ir::MethodId* method_id = method.GetMethodId();
+ dex_ir::CodeItem* code_item = method.GetCodeItem();
if (code_item != nullptr && code_item->DebugInfo() != nullptr) {
const uint32_t debug_info_offset = code_item->DebugInfo()->GetOffset();
const uint32_t method_idx = method_id->GetIndex();
@@ -248,8 +248,8 @@ void CompactDexWriter::SortDebugInfosByMethodIndex() {
for (auto& method : *(invoke_type == InvokeType::kDirect
? class_data->DirectMethods()
: class_data->VirtualMethods())) {
- const dex_ir::MethodId* method_id = method->GetMethodId();
- dex_ir::CodeItem* code_item = method->GetCodeItem();
+ const dex_ir::MethodId* method_id = method.GetMethodId();
+ dex_ir::CodeItem* code_item = method.GetCodeItem();
if (code_item != nullptr && code_item->DebugInfo() != nullptr) {
const dex_ir::DebugInfoItem* debug_item = code_item->DebugInfo();
method_idx_map.insert(std::make_pair(debug_item, method_id->GetIndex()));
@@ -350,8 +350,8 @@ bool CompactDexWriter::CanGenerateCompactDex(std::string* error_msg) {
for (auto& method : *(invoke_type == InvokeType::kDirect
? class_data->DirectMethods()
: class_data->VirtualMethods())) {
- const uint32_t idx = method->GetMethodId()->GetIndex();
- dex_ir::CodeItem* code_item = method->GetCodeItem();
+ const uint32_t idx = method.GetMethodId()->GetIndex();
+ dex_ir::CodeItem* code_item = method.GetCodeItem();
dex_ir:: DebugInfoItem* debug_info_item = nullptr;
if (code_item != nullptr) {
debug_info_item = code_item->DebugInfo();
diff --git a/dexlayout/dex_ir.cc b/dexlayout/dex_ir.cc
index b7d9db6da5..15e3baf18a 100644
--- a/dexlayout/dex_ir.cc
+++ b/dexlayout/dex_ir.cc
@@ -318,17 +318,22 @@ void Collections::ReadEncodedValue(const DexFile& dex_file,
void Collections::CreateStringId(const DexFile& dex_file, uint32_t i) {
const DexFile::StringId& disk_string_id = dex_file.GetStringId(dex::StringIndex(i));
- StringData* string_data = new StringData(dex_file.GetStringData(disk_string_id));
- AddItem(string_datas_map_, string_datas_, string_data, disk_string_id.string_data_off_);
-
- StringId* string_id = new StringId(string_data);
- AddIndexedItem(string_ids_, string_id, StringIdsOffset() + i * StringId::ItemSize(), i);
+ StringData* string_data = CreateAndAddItem(string_datas_map_,
+ string_datas_,
+ disk_string_id.string_data_off_,
+ dex_file.GetStringData(disk_string_id));
+ CreateAndAddIndexedItem(string_ids_,
+ StringIdsOffset() + i * StringId::ItemSize(),
+ i,
+ string_data);
}
void Collections::CreateTypeId(const DexFile& dex_file, uint32_t i) {
const DexFile::TypeId& disk_type_id = dex_file.GetTypeId(dex::TypeIndex(i));
- TypeId* type_id = new TypeId(GetStringId(disk_type_id.descriptor_idx_.index_));
- AddIndexedItem(type_ids_, type_id, TypeIdsOffset() + i * TypeId::ItemSize(), i);
+ CreateAndAddIndexedItem(type_ids_,
+ TypeIdsOffset() + i * TypeId::ItemSize(),
+ i,
+ GetStringId(disk_type_id.descriptor_idx_.index_));
}
void Collections::CreateProtoId(const DexFile& dex_file, uint32_t i) {
@@ -336,26 +341,32 @@ void Collections::CreateProtoId(const DexFile& dex_file, uint32_t i) {
const DexFile::TypeList* type_list = dex_file.GetProtoParameters(disk_proto_id);
TypeList* parameter_type_list = CreateTypeList(type_list, disk_proto_id.parameters_off_);
- ProtoId* proto_id = new ProtoId(GetStringId(disk_proto_id.shorty_idx_.index_),
- GetTypeId(disk_proto_id.return_type_idx_.index_),
- parameter_type_list);
- AddIndexedItem(proto_ids_, proto_id, ProtoIdsOffset() + i * ProtoId::ItemSize(), i);
+ CreateAndAddIndexedItem(proto_ids_,
+ ProtoIdsOffset() + i * ProtoId::ItemSize(),
+ i,
+ GetStringId(disk_proto_id.shorty_idx_.index_),
+ GetTypeId(disk_proto_id.return_type_idx_.index_),
+ parameter_type_list);
}
void Collections::CreateFieldId(const DexFile& dex_file, uint32_t i) {
const DexFile::FieldId& disk_field_id = dex_file.GetFieldId(i);
- FieldId* field_id = new FieldId(GetTypeId(disk_field_id.class_idx_.index_),
- GetTypeId(disk_field_id.type_idx_.index_),
- GetStringId(disk_field_id.name_idx_.index_));
- AddIndexedItem(field_ids_, field_id, FieldIdsOffset() + i * FieldId::ItemSize(), i);
+ CreateAndAddIndexedItem(field_ids_,
+ FieldIdsOffset() + i * FieldId::ItemSize(),
+ i,
+ GetTypeId(disk_field_id.class_idx_.index_),
+ GetTypeId(disk_field_id.type_idx_.index_),
+ GetStringId(disk_field_id.name_idx_.index_));
}
void Collections::CreateMethodId(const DexFile& dex_file, uint32_t i) {
const DexFile::MethodId& disk_method_id = dex_file.GetMethodId(i);
- MethodId* method_id = new MethodId(GetTypeId(disk_method_id.class_idx_.index_),
- GetProtoId(disk_method_id.proto_idx_.index_),
- GetStringId(disk_method_id.name_idx_.index_));
- AddIndexedItem(method_ids_, method_id, MethodIdsOffset() + i * MethodId::ItemSize(), i);
+ CreateAndAddIndexedItem(method_ids_,
+ MethodIdsOffset() + i * MethodId::ItemSize(),
+ i,
+ GetTypeId(disk_method_id.class_idx_.index_),
+ GetProtoId(disk_method_id.proto_idx_.index_),
+ GetStringId(disk_method_id.name_idx_.index_));
}
void Collections::CreateClassDef(const DexFile& dex_file, uint32_t i) {
@@ -382,9 +393,17 @@ void Collections::CreateClassDef(const DexFile& dex_file, uint32_t i) {
CreateEncodedArrayItem(dex_file, static_data, disk_class_def.static_values_off_);
ClassData* class_data = CreateClassData(
dex_file, dex_file.GetClassData(disk_class_def), disk_class_def.class_data_off_);
- ClassDef* class_def = new ClassDef(class_type, access_flags, superclass, interfaces_type_list,
- source_file, annotations, static_values, class_data);
- AddIndexedItem(class_defs_, class_def, ClassDefsOffset() + i * ClassDef::ItemSize(), i);
+ CreateAndAddIndexedItem(class_defs_,
+ ClassDefsOffset() + i * ClassDef::ItemSize(),
+ i,
+ class_type,
+ access_flags,
+ superclass,
+ interfaces_type_list,
+ source_file,
+ annotations,
+ static_values,
+ class_data);
}
TypeList* Collections::CreateTypeList(const DexFile::TypeList* dex_type_list, uint32_t offset) {
@@ -398,8 +417,7 @@ TypeList* Collections::CreateTypeList(const DexFile::TypeList* dex_type_list, ui
for (uint32_t index = 0; index < size; ++index) {
type_vector->push_back(GetTypeId(dex_type_list->GetTypeItem(index).type_idx_.index_));
}
- type_list = new TypeList(type_vector);
- AddItem(type_lists_map_, type_lists_, type_list, offset);
+ type_list = CreateAndAddItem(type_lists_map_, type_lists_, offset, type_vector);
}
return type_list;
}
@@ -418,8 +436,10 @@ EncodedArrayItem* Collections::CreateEncodedArrayItem(const DexFile& dex_file,
values->push_back(std::unique_ptr<EncodedValue>(ReadEncodedValue(dex_file, &static_data)));
}
// TODO: Calculate the size of the encoded array.
- encoded_array_item = new EncodedArrayItem(values);
- AddItem(encoded_array_items_map_, encoded_array_items_, encoded_array_item, offset);
+ encoded_array_item = CreateAndAddItem(encoded_array_items_map_,
+ encoded_array_items_,
+ offset,
+ values);
}
return encoded_array_item;
}
@@ -447,9 +467,12 @@ AnnotationItem* Collections::CreateAnnotationItem(const DexFile& dex_file,
const uint8_t* annotation_data = annotation->annotation_;
std::unique_ptr<EncodedValue> encoded_value(
ReadEncodedValue(dex_file, &annotation_data, DexFile::kDexAnnotationAnnotation, 0));
- annotation_item = new AnnotationItem(visibility, encoded_value->ReleaseEncodedAnnotation());
+ annotation_item = CreateAndAddItem(annotation_items_map_,
+ annotation_items_,
+ offset,
+ visibility,
+ encoded_value->ReleaseEncodedAnnotation());
annotation_item->SetSize(annotation_data - start_data);
- AddItem(annotation_items_map_, annotation_items_, annotation_item, offset);
}
return annotation_item;
}
@@ -472,8 +495,10 @@ AnnotationSetItem* Collections::CreateAnnotationSetItem(const DexFile& dex_file,
AnnotationItem* annotation_item = CreateAnnotationItem(dex_file, annotation);
items->push_back(annotation_item);
}
- annotation_set_item = new AnnotationSetItem(items);
- AddItem(annotation_set_items_map_, annotation_set_items_, annotation_set_item, offset);
+ annotation_set_item = CreateAndAddItem(annotation_set_items_map_,
+ annotation_set_items_,
+ offset,
+ items);
}
return annotation_set_item;
}
@@ -538,13 +563,13 @@ AnnotationsDirectoryItem* Collections::CreateAnnotationsDirectoryItem(const DexF
}
}
// TODO: Calculate the size of the annotations directory.
-annotations_directory_item = new AnnotationsDirectoryItem(
- class_annotation, field_annotations, method_annotations, parameter_annotations);
- AddItem(annotations_directory_items_map_,
- annotations_directory_items_,
- annotations_directory_item,
- offset);
- return annotations_directory_item;
+ return CreateAndAddItem(annotations_directory_items_map_,
+ annotations_directory_items_,
+ offset,
+ class_annotation,
+ field_annotations,
+ method_annotations,
+ parameter_annotations);
}
ParameterAnnotation* Collections::GenerateParameterAnnotation(
@@ -559,8 +584,10 @@ ParameterAnnotation* Collections::GenerateParameterAnnotation(
uint32_t set_offset = annotation_set_ref_list->list_[i].annotations_off_;
annotations->push_back(CreateAnnotationSetItem(dex_file, annotation_set_item, set_offset));
}
- set_ref_list = new AnnotationSetRefList(annotations);
- AddItem(annotation_set_ref_lists_map_, annotation_set_ref_lists_, set_ref_list, offset);
+ set_ref_list = CreateAndAddItem(annotation_set_ref_lists_map_,
+ annotation_set_ref_lists_,
+ offset,
+ annotations);
}
return new ParameterAnnotation(method_id, set_ref_list);
}
@@ -590,8 +617,11 @@ CodeItem* Collections::DedupeOrCreateCodeItem(const DexFile& dex_file,
uint32_t debug_info_size = GetDebugInfoStreamSize(debug_info_stream);
uint8_t* debug_info_buffer = new uint8_t[debug_info_size];
memcpy(debug_info_buffer, debug_info_stream, debug_info_size);
- debug_info = new DebugInfoItem(debug_info_size, debug_info_buffer);
- AddItem(debug_info_items_map_, debug_info_items_, debug_info, debug_info_offset);
+ debug_info = CreateAndAddItem(debug_info_items_map_,
+ debug_info_items_,
+ debug_info_offset,
+ debug_info_size,
+ debug_info_buffer);
}
}
@@ -677,14 +707,14 @@ CodeItem* Collections::DedupeOrCreateCodeItem(const DexFile& dex_file,
}
uint32_t size = dex_file.GetCodeItemSize(*disk_code_item);
- CodeItem* code_item = new CodeItem(accessor.RegistersSize(),
- accessor.InsSize(),
- accessor.OutsSize(),
- debug_info,
- insns_size,
- insns,
- tries,
- handler_list);
+ CodeItem* code_item = code_items_.CreateAndAddItem(accessor.RegistersSize(),
+ accessor.InsSize(),
+ accessor.OutsSize(),
+ debug_info,
+ insns_size,
+ insns,
+ tries,
+ handler_list);
code_item->SetSize(size);
// Add the code item to the map.
@@ -693,7 +723,6 @@ CodeItem* Collections::DedupeOrCreateCodeItem(const DexFile& dex_file,
code_item->SetOffset(offset);
}
code_items_map_.emplace(offsets_pair, code_item);
- code_items_.AddItem(code_item);
// Add "fixup" references to types, strings, methods, and fields.
// This is temporary, as we will probably want more detailed parsing of the
@@ -718,7 +747,7 @@ CodeItem* Collections::DedupeOrCreateCodeItem(const DexFile& dex_file,
return code_item;
}
-MethodItem* Collections::GenerateMethodItem(const DexFile& dex_file, ClassDataItemIterator& cdii) {
+MethodItem Collections::GenerateMethodItem(const DexFile& dex_file, ClassDataItemIterator& cdii) {
MethodId* method_id = GetMethodId(cdii.GetMemberIndex());
uint32_t access_flags = cdii.GetRawMemberAccessFlags();
const DexFile::CodeItem* disk_code_item = cdii.GetMethodCodeItem();
@@ -728,7 +757,7 @@ MethodItem* Collections::GenerateMethodItem(const DexFile& dex_file, ClassDataIt
disk_code_item,
cdii.GetMethodCodeItemOffset(),
cdii.GetMemberIndex());
- return new MethodItem(access_flags, method_id, code_item);
+ return MethodItem(access_flags, method_id, code_item);
}
ClassData* Collections::CreateClassData(
@@ -743,29 +772,33 @@ ClassData* Collections::CreateClassData(
for (; cdii.HasNextStaticField(); cdii.Next()) {
FieldId* field_item = GetFieldId(cdii.GetMemberIndex());
uint32_t access_flags = cdii.GetRawMemberAccessFlags();
- static_fields->push_back(std::unique_ptr<FieldItem>(new FieldItem(access_flags, field_item)));
+ static_fields->emplace_back(access_flags, field_item);
}
// Instance fields.
FieldItemVector* instance_fields = new FieldItemVector();
for (; cdii.HasNextInstanceField(); cdii.Next()) {
FieldId* field_item = GetFieldId(cdii.GetMemberIndex());
uint32_t access_flags = cdii.GetRawMemberAccessFlags();
- instance_fields->push_back(
- std::unique_ptr<FieldItem>(new FieldItem(access_flags, field_item)));
+ instance_fields->emplace_back(access_flags, field_item);
}
// Direct methods.
MethodItemVector* direct_methods = new MethodItemVector();
for (; cdii.HasNextDirectMethod(); cdii.Next()) {
- direct_methods->push_back(std::unique_ptr<MethodItem>(GenerateMethodItem(dex_file, cdii)));
+ direct_methods->push_back(GenerateMethodItem(dex_file, cdii));
}
// Virtual methods.
MethodItemVector* virtual_methods = new MethodItemVector();
for (; cdii.HasNextVirtualMethod(); cdii.Next()) {
- virtual_methods->push_back(std::unique_ptr<MethodItem>(GenerateMethodItem(dex_file, cdii)));
+ virtual_methods->push_back(GenerateMethodItem(dex_file, cdii));
}
- class_data = new ClassData(static_fields, instance_fields, direct_methods, virtual_methods);
+ class_data = CreateAndAddItem(class_datas_map_,
+ class_datas_,
+ offset,
+ static_fields,
+ instance_fields,
+ direct_methods,
+ virtual_methods);
class_data->SetSize(cdii.EndDataPointer() - encoded_data);
- AddItem(class_datas_map_, class_datas_, class_data, offset);
}
return class_data;
}
@@ -802,8 +835,10 @@ void Collections::CreateCallSiteId(const DexFile& dex_file, uint32_t i) {
EncodedArrayItem* call_site_item =
CreateEncodedArrayItem(dex_file, disk_call_item_ptr, disk_call_site_id.data_off_);
- CallSiteId* call_site_id = new CallSiteId(call_site_item);
- AddIndexedItem(call_site_ids_, call_site_id, CallSiteIdsOffset() + i * CallSiteId::ItemSize(), i);
+ CreateAndAddIndexedItem(call_site_ids_,
+ CallSiteIdsOffset() + i * CallSiteId::ItemSize(),
+ i,
+ call_site_item);
}
void Collections::CreateMethodHandleItem(const DexFile& dex_file, uint32_t i) {
@@ -824,11 +859,11 @@ void Collections::CreateMethodHandleItem(const DexFile& dex_file, uint32_t i) {
} else {
field_or_method_id = GetFieldId(index);
}
- MethodHandleItem* method_handle = new MethodHandleItem(type, field_or_method_id);
- AddIndexedItem(method_handle_items_,
- method_handle,
- MethodHandleItemsOffset() + i * MethodHandleItem::ItemSize(),
- i);
+ CreateAndAddIndexedItem(method_handle_items_,
+ MethodHandleItemsOffset() + i * MethodHandleItem::ItemSize(),
+ i,
+ type,
+ field_or_method_id);
}
void Collections::SortVectorsByMapOrder() {
@@ -844,6 +879,19 @@ void Collections::SortVectorsByMapOrder() {
class_datas_.SortByMapOrder(class_datas_map_.Collection());
}
+void Collections::ClearMaps() {
+ string_datas_map_.Collection().clear();
+ type_lists_map_.Collection().clear();
+ encoded_array_items_map_.Collection().clear();
+ annotation_items_map_.Collection().clear();
+ annotation_set_items_map_.Collection().clear();
+ annotation_set_ref_lists_map_.Collection().clear();
+ annotations_directory_items_map_.Collection().clear();
+ debug_info_items_map_.Collection().clear();
+ code_items_map_.clear();
+ class_datas_map_.Collection().clear();
+}
+
static uint32_t HeaderOffset(const dex_ir::Collections& collections ATTRIBUTE_UNUSED) {
return 0;
}
diff --git a/dexlayout/dex_ir.h b/dexlayout/dex_ir.h
index 5ecad2bf87..54ff105820 100644
--- a/dexlayout/dex_ir.h
+++ b/dexlayout/dex_ir.h
@@ -129,7 +129,11 @@ template<class T> class CollectionBase {
template<class T> class CollectionVector : public CollectionBase<T> {
public:
using Vector = std::vector<std::unique_ptr<T>>;
- CollectionVector() = default;
+ CollectionVector() { }
+ explicit CollectionVector(size_t size) {
+ // Preallocate so that assignment does not invalidate pointers into the vector.
+ collection_.reserve(size);
+ }
uint32_t Size() const { return collection_.size(); }
Vector& Collection() { return collection_; }
@@ -152,8 +156,11 @@ template<class T> class CollectionVector : public CollectionBase<T> {
protected:
Vector collection_;
- void AddItem(T* object) {
+ template<class... Args>
+ T* CreateAndAddItem(Args&&... args) {
+ T* object = new T(std::forward<Args>(args)...);
collection_.push_back(std::unique_ptr<T>(object));
+ return object;
}
private:
@@ -165,11 +172,20 @@ template<class T> class IndexedCollectionVector : public CollectionVector<T> {
public:
using Vector = std::vector<std::unique_ptr<T>>;
IndexedCollectionVector() = default;
+ explicit IndexedCollectionVector(size_t size) : CollectionVector<T>(size) { }
private:
- void AddIndexedItem(T* object, uint32_t index) {
+ template <class... Args>
+ T* CreateAndAddIndexedItem(uint32_t index, Args&&... args) {
+ T* object = CollectionVector<T>::CreateAndAddItem(std::forward<Args>(args)...);
object->SetIndex(index);
- CollectionVector<T>::collection_.push_back(std::unique_ptr<T>(object));
+ return object;
+ }
+
+ T* GetElement(uint32_t index) {
+ DCHECK_LT(index, CollectionVector<T>::Size());
+ DCHECK_NE(CollectionVector<T>::collection_[index].get(), static_cast<T*>(nullptr));
+ return CollectionVector<T>::collection_[index].get();
}
friend class Collections;
@@ -193,6 +209,8 @@ template<class T> class CollectionMap : public CollectionBase<T> {
private:
std::map<uint32_t, T*> collection_;
+ // CollectionMaps do not own the objects they contain, therefore AddItem is supported
+ // rather than CreateAndAddItem.
void AddItem(T* object, uint32_t offset) {
auto it = collection_.emplace(offset, object);
CHECK(it.second) << "CollectionMap already has an object with offset " << offset << " "
@@ -206,13 +224,25 @@ template<class T> class CollectionMap : public CollectionBase<T> {
class Collections {
public:
Collections() = default;
-
- CollectionVector<StringId>::Vector& StringIds() { return string_ids_.Collection(); }
- CollectionVector<TypeId>::Vector& TypeIds() { return type_ids_.Collection(); }
- CollectionVector<ProtoId>::Vector& ProtoIds() { return proto_ids_.Collection(); }
- CollectionVector<FieldId>::Vector& FieldIds() { return field_ids_.Collection(); }
- CollectionVector<MethodId>::Vector& MethodIds() { return method_ids_.Collection(); }
- CollectionVector<ClassDef>::Vector& ClassDefs() { return class_defs_.Collection(); }
+ Collections(uint32_t num_string_ids,
+ uint32_t num_type_ids,
+ uint32_t num_proto_ids,
+ uint32_t num_field_ids,
+ uint32_t num_method_ids,
+ uint32_t num_class_defs)
+ : string_ids_(num_string_ids),
+ type_ids_(num_type_ids),
+ proto_ids_(num_proto_ids),
+ field_ids_(num_field_ids),
+ method_ids_(num_method_ids),
+ class_defs_(num_class_defs) { }
+
+ IndexedCollectionVector<StringId>::Vector& StringIds() { return string_ids_.Collection(); }
+ IndexedCollectionVector<TypeId>::Vector& TypeIds() { return type_ids_.Collection(); }
+ IndexedCollectionVector<ProtoId>::Vector& ProtoIds() { return proto_ids_.Collection(); }
+ IndexedCollectionVector<FieldId>::Vector& FieldIds() { return field_ids_.Collection(); }
+ IndexedCollectionVector<MethodId>::Vector& MethodIds() { return method_ids_.Collection(); }
+ IndexedCollectionVector<ClassDef>::Vector& ClassDefs() { return class_defs_.Collection(); }
CollectionVector<CallSiteId>::Vector& CallSiteIds() { return call_site_ids_.Collection(); }
CollectionVector<MethodHandleItem>::Vector& MethodHandleItems()
{ return method_handle_items_.Collection(); }
@@ -266,28 +296,22 @@ class Collections {
uint32_t count);
StringId* GetStringId(uint32_t index) {
- CHECK_LT(index, StringIdsSize());
- return StringIds()[index].get();
+ return string_ids_.GetElement(index);
}
TypeId* GetTypeId(uint32_t index) {
- CHECK_LT(index, TypeIdsSize());
- return TypeIds()[index].get();
+ return type_ids_.GetElement(index);
}
ProtoId* GetProtoId(uint32_t index) {
- CHECK_LT(index, ProtoIdsSize());
- return ProtoIds()[index].get();
+ return proto_ids_.GetElement(index);
}
FieldId* GetFieldId(uint32_t index) {
- CHECK_LT(index, FieldIdsSize());
- return FieldIds()[index].get();
+ return field_ids_.GetElement(index);
}
MethodId* GetMethodId(uint32_t index) {
- CHECK_LT(index, MethodIdsSize());
- return MethodIds()[index].get();
+ return method_ids_.GetElement(index);
}
ClassDef* GetClassDef(uint32_t index) {
- CHECK_LT(index, ClassDefsSize());
- return ClassDefs()[index].get();
+ return class_defs_.GetElement(index);
}
CallSiteId* GetCallSiteId(uint32_t index) {
CHECK_LT(index, CallSiteIdsSize());
@@ -372,31 +396,35 @@ class Collections {
// Sort the vectors buy map order (same order that was used in the input file).
void SortVectorsByMapOrder();
-
- template <typename Type>
- void AddItem(CollectionMap<Type>& map,
- CollectionVector<Type>& vector,
- Type* item,
- uint32_t offset) {
+ // Empty the maps, which are only used for IR construction.
+ void ClearMaps();
+
+ template <typename Type, class... Args>
+ Type* CreateAndAddItem(CollectionMap<Type>& map,
+ CollectionVector<Type>& vector,
+ uint32_t offset,
+ Args&&... args) {
+ Type* item = vector.CreateAndAddItem(std::forward<Args>(args)...);
DCHECK(!map.GetExistingObject(offset));
DCHECK(!item->OffsetAssigned());
if (eagerly_assign_offsets_) {
item->SetOffset(offset);
}
map.AddItem(item, offset);
- vector.AddItem(item);
+ return item;
}
- template <typename Type>
- void AddIndexedItem(IndexedCollectionVector<Type>& vector,
- Type* item,
- uint32_t offset,
- uint32_t index) {
+ template <typename Type, class... Args>
+ Type* CreateAndAddIndexedItem(IndexedCollectionVector<Type>& vector,
+ uint32_t offset,
+ uint32_t index,
+ Args&&... args) {
+ Type* item = vector.CreateAndAddIndexedItem(index, std::forward<Args>(args)...);
DCHECK(!item->OffsetAssigned());
if (eagerly_assign_offsets_) {
item->SetOffset(offset);
}
- vector.AddIndexedItem(item, index);
+ return item;
}
void SetEagerlyAssignOffsets(bool eagerly_assign_offsets) {
@@ -425,7 +453,7 @@ class Collections {
ParameterAnnotation* GenerateParameterAnnotation(const DexFile& dex_file, MethodId* method_id,
const DexFile::AnnotationSetRefList* annotation_set_ref_list, uint32_t offset);
- MethodItem* GenerateMethodItem(const DexFile& dex_file, ClassDataItemIterator& cdii);
+ MethodItem GenerateMethodItem(const DexFile& dex_file, ClassDataItemIterator& cdii);
// Collection vectors own the IR data.
IndexedCollectionVector<StringId> string_ids_;
@@ -433,6 +461,7 @@ class Collections {
IndexedCollectionVector<ProtoId> proto_ids_;
IndexedCollectionVector<FieldId> field_ids_;
IndexedCollectionVector<MethodId> method_ids_;
+ IndexedCollectionVector<ClassDef> class_defs_;
IndexedCollectionVector<CallSiteId> call_site_ids_;
IndexedCollectionVector<MethodHandleItem> method_handle_items_;
IndexedCollectionVector<StringData> string_datas_;
@@ -442,7 +471,6 @@ class Collections {
IndexedCollectionVector<AnnotationSetItem> annotation_set_items_;
IndexedCollectionVector<AnnotationSetRefList> annotation_set_ref_lists_;
IndexedCollectionVector<AnnotationsDirectoryItem> annotations_directory_items_;
- IndexedCollectionVector<ClassDef> class_defs_;
// The order of the vectors controls the layout of the output file by index order, to change the
// layout just sort the vector. Note that you may only change the order of the non indexed vectors
// below. Indexed vectors are accessed by indices in other places, changing the sorting order will
@@ -485,6 +513,8 @@ class Item {
Item() { }
virtual ~Item() { }
+ Item(Item&&) = default;
+
// Return the assigned offset.
uint32_t GetOffset() const WARN_UNUSED {
CHECK(OffsetAssigned());
@@ -536,18 +566,54 @@ class Header : public Item {
uint32_t data_size,
uint32_t data_offset,
bool support_default_methods)
+ : Item(0, kHeaderItemSize), support_default_methods_(support_default_methods) {
+ ConstructorHelper(magic,
+ checksum,
+ signature,
+ endian_tag,
+ file_size,
+ header_size,
+ link_size,
+ link_offset,
+ data_size,
+ data_offset);
+ }
+
+ Header(const uint8_t* magic,
+ uint32_t checksum,
+ const uint8_t* signature,
+ uint32_t endian_tag,
+ uint32_t file_size,
+ uint32_t header_size,
+ uint32_t link_size,
+ uint32_t link_offset,
+ uint32_t data_size,
+ uint32_t data_offset,
+ bool support_default_methods,
+ uint32_t num_string_ids,
+ uint32_t num_type_ids,
+ uint32_t num_proto_ids,
+ uint32_t num_field_ids,
+ uint32_t num_method_ids,
+ uint32_t num_class_defs)
: Item(0, kHeaderItemSize),
- checksum_(checksum),
- endian_tag_(endian_tag),
- file_size_(file_size),
- header_size_(header_size),
- link_size_(link_size),
- link_offset_(link_offset),
- data_size_(data_size),
- data_offset_(data_offset),
- support_default_methods_(support_default_methods) {
- memcpy(magic_, magic, sizeof(magic_));
- memcpy(signature_, signature, sizeof(signature_));
+ support_default_methods_(support_default_methods),
+ collections_(num_string_ids,
+ num_type_ids,
+ num_proto_ids,
+ num_field_ids,
+ num_method_ids,
+ num_class_defs) {
+ ConstructorHelper(magic,
+ checksum,
+ signature,
+ endian_tag,
+ file_size,
+ header_size,
+ link_size,
+ link_offset,
+ data_size,
+ data_offset);
}
~Header() OVERRIDE { }
@@ -596,6 +662,27 @@ class Header : public Item {
uint32_t data_offset_;
const bool support_default_methods_;
+ void ConstructorHelper(const uint8_t* magic,
+ uint32_t checksum,
+ const uint8_t* signature,
+ uint32_t endian_tag,
+ uint32_t file_size,
+ uint32_t header_size,
+ uint32_t link_size,
+ uint32_t link_offset,
+ uint32_t data_size,
+ uint32_t data_offset) {
+ checksum_ = checksum;
+ endian_tag_ = endian_tag;
+ file_size_ = file_size;
+ header_size_ = header_size;
+ link_size_ = link_size;
+ link_offset_ = link_offset;
+ data_size_ = data_size;
+ data_offset_ = data_offset;
+ memcpy(magic_, magic, sizeof(magic_));
+ memcpy(signature_, signature, sizeof(signature_));
+ }
Collections collections_;
DISALLOW_COPY_AND_ASSIGN(Header);
@@ -744,6 +831,8 @@ class FieldItem : public Item {
: access_flags_(access_flags), field_id_(field_id) { }
~FieldItem() OVERRIDE { }
+ FieldItem(FieldItem&&) = default;
+
uint32_t GetAccessFlags() const { return access_flags_; }
const FieldId* GetFieldId() const { return field_id_; }
@@ -756,7 +845,7 @@ class FieldItem : public Item {
DISALLOW_COPY_AND_ASSIGN(FieldItem);
};
-using FieldItemVector = std::vector<std::unique_ptr<FieldItem>>;
+using FieldItemVector = std::vector<FieldItem>;
class MethodItem : public Item {
public:
@@ -764,6 +853,8 @@ class MethodItem : public Item {
: access_flags_(access_flags), method_id_(method_id), code_(code) { }
~MethodItem() OVERRIDE { }
+ MethodItem(MethodItem&&) = default;
+
uint32_t GetAccessFlags() const { return access_flags_; }
const MethodId* GetMethodId() const { return method_id_; }
CodeItem* GetCodeItem() { return code_; }
@@ -778,7 +869,7 @@ class MethodItem : public Item {
DISALLOW_COPY_AND_ASSIGN(MethodItem);
};
-using MethodItemVector = std::vector<std::unique_ptr<MethodItem>>;
+using MethodItemVector = std::vector<MethodItem>;
class EncodedValue {
public:
diff --git a/dexlayout/dex_ir_builder.cc b/dexlayout/dex_ir_builder.cc
index 4f9bcdd742..9468f763d6 100644
--- a/dexlayout/dex_ir_builder.cc
+++ b/dexlayout/dex_ir_builder.cc
@@ -43,7 +43,13 @@ Header* DexIrBuilder(const DexFile& dex_file,
disk_header.link_off_,
disk_header.data_size_,
disk_header.data_off_,
- dex_file.SupportsDefaultMethods());
+ dex_file.SupportsDefaultMethods(),
+ dex_file.NumStringIds(),
+ dex_file.NumTypeIds(),
+ dex_file.NumProtoIds(),
+ dex_file.NumFieldIds(),
+ dex_file.NumMethodIds(),
+ dex_file.NumClassDefs());
Collections& collections = header->GetCollections();
collections.SetEagerlyAssignOffsets(eagerly_assign_offsets);
// Walk the rest of the header fields.
@@ -94,6 +100,7 @@ Header* DexIrBuilder(const DexFile& dex_file,
// Sort the vectors by the map order (same order as the file).
collections.SortVectorsByMapOrder();
+ collections.ClearMaps();
// Load the link data if it exists.
collections.SetLinkData(std::vector<uint8_t>(
diff --git a/dexlayout/dex_verify.cc b/dexlayout/dex_verify.cc
index 18ddc86e0c..2e4756b482 100644
--- a/dexlayout/dex_verify.cc
+++ b/dexlayout/dex_verify.cc
@@ -769,8 +769,8 @@ bool VerifyFields(dex_ir::FieldItemVector* orig,
return false;
}
for (size_t i = 0; i < orig->size(); ++i) {
- dex_ir::FieldItem* orig_field = (*orig)[i].get();
- dex_ir::FieldItem* output_field = (*output)[i].get();
+ dex_ir::FieldItem* orig_field = &(*orig)[i];
+ dex_ir::FieldItem* output_field = &(*output)[i];
if (orig_field->GetFieldId()->GetIndex() != output_field->GetFieldId()->GetIndex()) {
*error_msg = StringPrintf("Mismatched field index for class data at offset %x: %u vs %u.",
orig_offset,
@@ -802,8 +802,8 @@ bool VerifyMethods(dex_ir::MethodItemVector* orig,
return false;
}
for (size_t i = 0; i < orig->size(); ++i) {
- dex_ir::MethodItem* orig_method = (*orig)[i].get();
- dex_ir::MethodItem* output_method = (*output)[i].get();
+ dex_ir::MethodItem* orig_method = &(*orig)[i];
+ dex_ir::MethodItem* output_method = &(*output)[i];
if (orig_method->GetMethodId()->GetIndex() != output_method->GetMethodId()->GetIndex()) {
*error_msg = StringPrintf("Mismatched method index for class data at offset %x: %u vs %u.",
orig_offset,
diff --git a/dexlayout/dex_visualize.cc b/dexlayout/dex_visualize.cc
index c8aac941ff..0e04c587e7 100644
--- a/dexlayout/dex_visualize.cc
+++ b/dexlayout/dex_visualize.cc
@@ -279,22 +279,22 @@ void VisualizeDexLayout(dex_ir::Header* header,
dumper->DumpAddressRange(class_data, class_index);
if (class_data->StaticFields()) {
for (auto& field_item : *class_data->StaticFields()) {
- dumper->DumpFieldItem(field_item.get(), class_index);
+ dumper->DumpFieldItem(&field_item, class_index);
}
}
if (class_data->InstanceFields()) {
for (auto& field_item : *class_data->InstanceFields()) {
- dumper->DumpFieldItem(field_item.get(), class_index);
+ dumper->DumpFieldItem(&field_item, class_index);
}
}
if (class_data->DirectMethods()) {
for (auto& method_item : *class_data->DirectMethods()) {
- dumper->DumpMethodItem(method_item.get(), dex_file, class_index, profile_info);
+ dumper->DumpMethodItem(&method_item, dex_file, class_index, profile_info);
}
}
if (class_data->VirtualMethods()) {
for (auto& method_item : *class_data->VirtualMethods()) {
- dumper->DumpMethodItem(method_item.get(), dex_file, class_index, profile_info);
+ dumper->DumpMethodItem(&method_item, dex_file, class_index, profile_info);
}
}
}
diff --git a/dexlayout/dex_writer.cc b/dexlayout/dex_writer.cc
index eead13f69a..9ed1312983 100644
--- a/dexlayout/dex_writer.cc
+++ b/dexlayout/dex_writer.cc
@@ -207,21 +207,21 @@ void DexWriter::WriteEncodedAnnotation(Stream* stream, dex_ir::EncodedAnnotation
void DexWriter::WriteEncodedFields(Stream* stream, dex_ir::FieldItemVector* fields) {
uint32_t prev_index = 0;
- for (std::unique_ptr<dex_ir::FieldItem>& field : *fields) {
- uint32_t index = field->GetFieldId()->GetIndex();
+ for (auto& field : *fields) {
+ uint32_t index = field.GetFieldId()->GetIndex();
stream->WriteUleb128(index - prev_index);
- stream->WriteUleb128(field->GetAccessFlags());
+ stream->WriteUleb128(field.GetAccessFlags());
prev_index = index;
}
}
void DexWriter::WriteEncodedMethods(Stream* stream, dex_ir::MethodItemVector* methods) {
uint32_t prev_index = 0;
- for (std::unique_ptr<dex_ir::MethodItem>& method : *methods) {
- uint32_t index = method->GetMethodId()->GetIndex();
- uint32_t code_off = method->GetCodeItem() == nullptr ? 0 : method->GetCodeItem()->GetOffset();
+ for (auto& method : *methods) {
+ uint32_t index = method.GetMethodId()->GetIndex();
+ uint32_t code_off = method.GetCodeItem() == nullptr ? 0 : method.GetCodeItem()->GetOffset();
stream->WriteUleb128(index - prev_index);
- stream->WriteUleb128(method->GetAccessFlags());
+ stream->WriteUleb128(method.GetAccessFlags());
stream->WriteUleb128(code_off);
prev_index = index;
}
diff --git a/dexlayout/dexlayout.cc b/dexlayout/dexlayout.cc
index 62dd1a9554..39d93bfc77 100644
--- a/dexlayout/dexlayout.cc
+++ b/dexlayout/dexlayout.cc
@@ -1459,8 +1459,8 @@ void DexLayout::DumpClass(int idx, char** last_package) {
dex_ir::FieldItemVector* static_fields = class_data->StaticFields();
if (static_fields != nullptr) {
for (uint32_t i = 0; i < static_fields->size(); i++) {
- DumpSField((*static_fields)[i]->GetFieldId()->GetIndex(),
- (*static_fields)[i]->GetAccessFlags(),
+ DumpSField((*static_fields)[i].GetFieldId()->GetIndex(),
+ (*static_fields)[i].GetAccessFlags(),
i,
i < encoded_values_size ? (*encoded_values)[i].get() : nullptr);
} // for
@@ -1475,8 +1475,8 @@ void DexLayout::DumpClass(int idx, char** last_package) {
dex_ir::FieldItemVector* instance_fields = class_data->InstanceFields();
if (instance_fields != nullptr) {
for (uint32_t i = 0; i < instance_fields->size(); i++) {
- DumpIField((*instance_fields)[i]->GetFieldId()->GetIndex(),
- (*instance_fields)[i]->GetAccessFlags(),
+ DumpIField((*instance_fields)[i].GetFieldId()->GetIndex(),
+ (*instance_fields)[i].GetAccessFlags(),
i);
} // for
}
@@ -1490,9 +1490,9 @@ void DexLayout::DumpClass(int idx, char** last_package) {
dex_ir::MethodItemVector* direct_methods = class_data->DirectMethods();
if (direct_methods != nullptr) {
for (uint32_t i = 0; i < direct_methods->size(); i++) {
- DumpMethod((*direct_methods)[i]->GetMethodId()->GetIndex(),
- (*direct_methods)[i]->GetAccessFlags(),
- (*direct_methods)[i]->GetCodeItem(),
+ DumpMethod((*direct_methods)[i].GetMethodId()->GetIndex(),
+ (*direct_methods)[i].GetAccessFlags(),
+ (*direct_methods)[i].GetCodeItem(),
i);
} // for
}
@@ -1506,9 +1506,9 @@ void DexLayout::DumpClass(int idx, char** last_package) {
dex_ir::MethodItemVector* virtual_methods = class_data->VirtualMethods();
if (virtual_methods != nullptr) {
for (uint32_t i = 0; i < virtual_methods->size(); i++) {
- DumpMethod((*virtual_methods)[i]->GetMethodId()->GetIndex(),
- (*virtual_methods)[i]->GetAccessFlags(),
- (*virtual_methods)[i]->GetCodeItem(),
+ DumpMethod((*virtual_methods)[i].GetMethodId()->GetIndex(),
+ (*virtual_methods)[i].GetAccessFlags(),
+ (*virtual_methods)[i].GetCodeItem(),
i);
} // for
}
@@ -1636,14 +1636,14 @@ void DexLayout::LayoutStringData(const DexFile* dex_file) {
}
for (size_t i = 0; i < 2; ++i) {
for (auto& method : *(i == 0 ? data->DirectMethods() : data->VirtualMethods())) {
- const dex_ir::MethodId* method_id = method->GetMethodId();
- dex_ir::CodeItem* code_item = method->GetCodeItem();
+ const dex_ir::MethodId* method_id = method.GetMethodId();
+ dex_ir::CodeItem* code_item = method.GetCodeItem();
if (code_item == nullptr) {
continue;
}
const bool is_clinit = is_profile_class &&
- (method->GetAccessFlags() & kAccConstructor) != 0 &&
- (method->GetAccessFlags() & kAccStatic) != 0;
+ (method.GetAccessFlags() & kAccConstructor) != 0 &&
+ (method.GetAccessFlags() & kAccStatic) != 0;
const bool method_executed = is_clinit ||
info_->GetMethodHotness(MethodReference(dex_file, method_id->GetIndex())).IsInProfile();
if (!method_executed) {
@@ -1744,14 +1744,14 @@ void DexLayout::LayoutCodeItems(const DexFile* dex_file) {
for (auto& method : *(invoke_type == InvokeType::kDirect
? class_data->DirectMethods()
: class_data->VirtualMethods())) {
- const dex_ir::MethodId *method_id = method->GetMethodId();
- dex_ir::CodeItem *code_item = method->GetCodeItem();
+ const dex_ir::MethodId *method_id = method.GetMethodId();
+ dex_ir::CodeItem *code_item = method.GetCodeItem();
if (code_item == nullptr) {
continue;
}
// Separate executed methods (clinits and profiled methods) from unexecuted methods.
- const bool is_clinit = (method->GetAccessFlags() & kAccConstructor) != 0 &&
- (method->GetAccessFlags() & kAccStatic) != 0;
+ const bool is_clinit = (method.GetAccessFlags() & kAccConstructor) != 0 &&
+ (method.GetAccessFlags() & kAccStatic) != 0;
const bool is_startup_clinit = is_profile_class && is_clinit;
using Hotness = ProfileCompilationInfo::MethodHotness;
Hotness hotness = info_->GetMethodHotness(MethodReference(dex_file, method_id->GetIndex()));