summaryrefslogtreecommitdiff
path: root/dexlayout/dex_ir.cc
diff options
context:
space:
mode:
Diffstat (limited to 'dexlayout/dex_ir.cc')
-rw-r--r--dexlayout/dex_ir.cc196
1 files changed, 109 insertions, 87 deletions
diff --git a/dexlayout/dex_ir.cc b/dexlayout/dex_ir.cc
index 3edb0a44f2..a8ba950c28 100644
--- a/dexlayout/dex_ir.cc
+++ b/dexlayout/dex_ir.cc
@@ -186,22 +186,28 @@ static bool GetIdsFromByteCode(Collections& collections,
return has_id;
}
-EncodedValue* Collections::ReadEncodedValue(const uint8_t** data) {
+EncodedValue* Collections::ReadEncodedValue(const DexFile& dex_file, const uint8_t** data) {
const uint8_t encoded_value = *(*data)++;
const uint8_t type = encoded_value & 0x1f;
EncodedValue* item = new EncodedValue(type);
- ReadEncodedValue(data, type, encoded_value >> 5, item);
+ ReadEncodedValue(dex_file, data, type, encoded_value >> 5, item);
return item;
}
-EncodedValue* Collections::ReadEncodedValue(const uint8_t** data, uint8_t type, uint8_t length) {
+EncodedValue* Collections::ReadEncodedValue(const DexFile& dex_file,
+ const uint8_t** data,
+ uint8_t type,
+ uint8_t length) {
EncodedValue* item = new EncodedValue(type);
- ReadEncodedValue(data, type, length, item);
+ ReadEncodedValue(dex_file, data, type, length, item);
return item;
}
-void Collections::ReadEncodedValue(
- const uint8_t** data, uint8_t type, uint8_t length, EncodedValue* item) {
+void Collections::ReadEncodedValue(const DexFile& dex_file,
+ const uint8_t** data,
+ uint8_t type,
+ uint8_t length,
+ EncodedValue* item) {
switch (type) {
case DexFile::kDexAnnotationByte:
item->SetByte(static_cast<int8_t>(ReadVarWidth(data, length, false)));
@@ -271,12 +277,17 @@ void Collections::ReadEncodedValue(
}
case DexFile::kDexAnnotationArray: {
EncodedValueVector* values = new EncodedValueVector();
+ const uint32_t offset = *data - dex_file.Begin();
const uint32_t size = DecodeUnsignedLeb128(data);
// Decode all elements.
for (uint32_t i = 0; i < size; i++) {
- values->push_back(std::unique_ptr<EncodedValue>(ReadEncodedValue(data)));
+ values->push_back(std::unique_ptr<EncodedValue>(ReadEncodedValue(dex_file, data)));
}
- item->SetEncodedArray(new EncodedArrayItem(values));
+ EncodedArrayItem* array_item = new EncodedArrayItem(values);
+ if (eagerly_assign_offsets_) {
+ array_item->SetOffset(offset);
+ }
+ item->SetEncodedArray(array_item);
break;
}
case DexFile::kDexAnnotationAnnotation: {
@@ -287,7 +298,7 @@ void Collections::ReadEncodedValue(
for (uint32_t i = 0; i < size; i++) {
const uint32_t name_index = DecodeUnsignedLeb128(data);
elements->push_back(std::unique_ptr<AnnotationElement>(
- new AnnotationElement(GetStringId(name_index), ReadEncodedValue(data))));
+ new AnnotationElement(GetStringId(name_index), ReadEncodedValue(dex_file, data))));
}
item->SetEncodedAnnotation(new EncodedAnnotation(GetTypeId(type_idx), elements));
break;
@@ -305,16 +316,16 @@ void Collections::ReadEncodedValue(
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));
- string_datas_.AddItem(string_data, disk_string_id.string_data_off_);
+ AddItem(string_datas_map_, string_datas_, string_data, disk_string_id.string_data_off_);
StringId* string_id = new StringId(string_data);
- string_ids_.AddIndexedItem(string_id, StringIdsOffset() + i * StringId::ItemSize(), i);
+ AddIndexedItem(string_ids_, string_id, StringIdsOffset() + i * StringId::ItemSize(), i);
}
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_));
- type_ids_.AddIndexedItem(type_id, TypeIdsOffset() + i * TypeId::ItemSize(), i);
+ AddIndexedItem(type_ids_, type_id, TypeIdsOffset() + i * TypeId::ItemSize(), i);
}
void Collections::CreateProtoId(const DexFile& dex_file, uint32_t i) {
@@ -325,7 +336,7 @@ void Collections::CreateProtoId(const DexFile& dex_file, uint32_t i) {
ProtoId* proto_id = new ProtoId(GetStringId(disk_proto_id.shorty_idx_.index_),
GetTypeId(disk_proto_id.return_type_idx_.index_),
parameter_type_list);
- proto_ids_.AddIndexedItem(proto_id, ProtoIdsOffset() + i * ProtoId::ItemSize(), i);
+ AddIndexedItem(proto_ids_, proto_id, ProtoIdsOffset() + i * ProtoId::ItemSize(), i);
}
void Collections::CreateFieldId(const DexFile& dex_file, uint32_t i) {
@@ -333,7 +344,7 @@ void Collections::CreateFieldId(const DexFile& dex_file, uint32_t 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_));
- field_ids_.AddIndexedItem(field_id, FieldIdsOffset() + i * FieldId::ItemSize(), i);
+ AddIndexedItem(field_ids_, field_id, FieldIdsOffset() + i * FieldId::ItemSize(), i);
}
void Collections::CreateMethodId(const DexFile& dex_file, uint32_t i) {
@@ -341,7 +352,7 @@ void Collections::CreateMethodId(const DexFile& dex_file, uint32_t i) {
MethodId* method_id = new MethodId(GetTypeId(disk_method_id.class_idx_.index_),
GetProtoId(disk_method_id.proto_idx_),
GetStringId(disk_method_id.name_idx_.index_));
- method_ids_.AddIndexedItem(method_id, MethodIdsOffset() + i * MethodId::ItemSize(), i);
+ AddIndexedItem(method_ids_, method_id, MethodIdsOffset() + i * MethodId::ItemSize(), i);
}
void Collections::CreateClassDef(const DexFile& dex_file, uint32_t i) {
@@ -365,48 +376,48 @@ void Collections::CreateClassDef(const DexFile& dex_file, uint32_t i) {
// Static field initializers.
const uint8_t* static_data = dex_file.GetEncodedStaticFieldValuesArray(disk_class_def);
EncodedArrayItem* static_values =
- CreateEncodedArrayItem(static_data, disk_class_def.static_values_off_);
+ 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);
- class_defs_.AddIndexedItem(class_def, ClassDefsOffset() + i * ClassDef::ItemSize(), i);
+ AddIndexedItem(class_defs_, class_def, ClassDefsOffset() + i * ClassDef::ItemSize(), i);
}
TypeList* Collections::CreateTypeList(const DexFile::TypeList* dex_type_list, uint32_t offset) {
if (dex_type_list == nullptr) {
return nullptr;
}
- auto found_type_list = TypeLists().find(offset);
- if (found_type_list != TypeLists().end()) {
- return found_type_list->second.get();
- }
- TypeIdVector* type_vector = new TypeIdVector();
- uint32_t size = dex_type_list->Size();
- for (uint32_t index = 0; index < size; ++index) {
- type_vector->push_back(GetTypeId(dex_type_list->GetTypeItem(index).type_idx_.index_));
+ TypeList* type_list = type_lists_map_.GetExistingObject(offset);
+ if (type_list == nullptr) {
+ TypeIdVector* type_vector = new TypeIdVector();
+ uint32_t size = dex_type_list->Size();
+ 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);
}
- TypeList* new_type_list = new TypeList(type_vector);
- type_lists_.AddItem(new_type_list, offset);
- return new_type_list;
+ return type_list;
}
-EncodedArrayItem* Collections::CreateEncodedArrayItem(const uint8_t* static_data, uint32_t offset) {
+EncodedArrayItem* Collections::CreateEncodedArrayItem(const DexFile& dex_file,
+ const uint8_t* static_data,
+ uint32_t offset) {
if (static_data == nullptr) {
return nullptr;
}
- auto found_encoded_array_item = EncodedArrayItems().find(offset);
- if (found_encoded_array_item != EncodedArrayItems().end()) {
- return found_encoded_array_item->second.get();
- }
- uint32_t size = DecodeUnsignedLeb128(&static_data);
- EncodedValueVector* values = new EncodedValueVector();
- for (uint32_t i = 0; i < size; ++i) {
- values->push_back(std::unique_ptr<EncodedValue>(ReadEncodedValue(&static_data)));
+ EncodedArrayItem* encoded_array_item = encoded_array_items_map_.GetExistingObject(offset);
+ if (encoded_array_item == nullptr) {
+ uint32_t size = DecodeUnsignedLeb128(&static_data);
+ EncodedValueVector* values = new EncodedValueVector();
+ for (uint32_t i = 0; i < size; ++i) {
+ 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);
}
- // TODO: Calculate the size of the encoded array.
- EncodedArrayItem* encoded_array_item = new EncodedArrayItem(values);
- encoded_array_items_.AddItem(encoded_array_item, offset);
return encoded_array_item;
}
@@ -427,19 +438,16 @@ AnnotationItem* Collections::CreateAnnotationItem(const DexFile& dex_file,
const DexFile::AnnotationItem* annotation) {
const uint8_t* const start_data = reinterpret_cast<const uint8_t*>(annotation);
const uint32_t offset = start_data - dex_file.Begin();
- auto found_annotation_item = AnnotationItems().find(offset);
- if (found_annotation_item != AnnotationItems().end()) {
- return found_annotation_item->second.get();
+ AnnotationItem* annotation_item = annotation_items_map_.GetExistingObject(offset);
+ if (annotation_item == nullptr) {
+ uint8_t visibility = annotation->visibility_;
+ 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->SetSize(annotation_data - start_data);
+ AddItem(annotation_items_map_, annotation_items_, annotation_item, offset);
}
- uint8_t visibility = annotation->visibility_;
- const uint8_t* annotation_data = annotation->annotation_;
- std::unique_ptr<EncodedValue> encoded_value(
- ReadEncodedValue(&annotation_data, DexFile::kDexAnnotationAnnotation, 0));
- AnnotationItem* annotation_item =
- new AnnotationItem(visibility, encoded_value->ReleaseEncodedAnnotation());
- annotation_item->SetOffset(offset);
- annotation_item->SetSize(annotation_data - start_data);
- annotation_items_.AddItem(annotation_item, annotation_item->GetOffset());
return annotation_item;
}
@@ -449,30 +457,30 @@ AnnotationSetItem* Collections::CreateAnnotationSetItem(const DexFile& dex_file,
if (disk_annotations_item == nullptr || (disk_annotations_item->size_ == 0 && offset == 0)) {
return nullptr;
}
- auto found_anno_set_item = AnnotationSetItems().find(offset);
- if (found_anno_set_item != AnnotationSetItems().end()) {
- return found_anno_set_item->second.get();
- }
- std::vector<AnnotationItem*>* items = new std::vector<AnnotationItem*>();
- for (uint32_t i = 0; i < disk_annotations_item->size_; ++i) {
- const DexFile::AnnotationItem* annotation =
- dex_file.GetAnnotationItem(disk_annotations_item, i);
- if (annotation == nullptr) {
- continue;
+ AnnotationSetItem* annotation_set_item = annotation_set_items_map_.GetExistingObject(offset);
+ if (annotation_set_item == nullptr) {
+ std::vector<AnnotationItem*>* items = new std::vector<AnnotationItem*>();
+ for (uint32_t i = 0; i < disk_annotations_item->size_; ++i) {
+ const DexFile::AnnotationItem* annotation =
+ dex_file.GetAnnotationItem(disk_annotations_item, i);
+ if (annotation == nullptr) {
+ continue;
+ }
+ AnnotationItem* annotation_item = CreateAnnotationItem(dex_file, annotation);
+ items->push_back(annotation_item);
}
- 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);
}
- AnnotationSetItem* annotation_set_item = new AnnotationSetItem(items);
- annotation_set_items_.AddItem(annotation_set_item, offset);
return annotation_set_item;
}
AnnotationsDirectoryItem* Collections::CreateAnnotationsDirectoryItem(const DexFile& dex_file,
const DexFile::AnnotationsDirectoryItem* disk_annotations_item, uint32_t offset) {
- auto found_anno_dir_item = AnnotationsDirectoryItems().find(offset);
- if (found_anno_dir_item != AnnotationsDirectoryItems().end()) {
- return found_anno_dir_item->second.get();
+ AnnotationsDirectoryItem* annotations_directory_item =
+ annotations_directory_items_map_.GetExistingObject(offset);
+ if (annotations_directory_item != nullptr) {
+ return annotations_directory_item;
}
const DexFile::AnnotationSetItem* class_set_item =
dex_file.GetClassAnnotationSet(disk_annotations_item);
@@ -527,20 +535,19 @@ AnnotationsDirectoryItem* Collections::CreateAnnotationsDirectoryItem(const DexF
}
}
// TODO: Calculate the size of the annotations directory.
- AnnotationsDirectoryItem* annotations_directory_item = new AnnotationsDirectoryItem(
+annotations_directory_item = new AnnotationsDirectoryItem(
class_annotation, field_annotations, method_annotations, parameter_annotations);
- annotations_directory_items_.AddItem(annotations_directory_item, offset);
+ AddItem(annotations_directory_items_map_,
+ annotations_directory_items_,
+ annotations_directory_item,
+ offset);
return annotations_directory_item;
}
ParameterAnnotation* Collections::GenerateParameterAnnotation(
const DexFile& dex_file, MethodId* method_id,
const DexFile::AnnotationSetRefList* annotation_set_ref_list, uint32_t offset) {
- AnnotationSetRefList* set_ref_list = nullptr;
- auto found_set_ref_list = AnnotationSetRefLists().find(offset);
- if (found_set_ref_list != AnnotationSetRefLists().end()) {
- set_ref_list = found_set_ref_list->second.get();
- }
+ AnnotationSetRefList* set_ref_list = annotation_set_ref_lists_map_.GetExistingObject(offset);
if (set_ref_list == nullptr) {
std::vector<AnnotationSetItem*>* annotations = new std::vector<AnnotationSetItem*>();
for (uint32_t i = 0; i < annotation_set_ref_list->size_; ++i) {
@@ -550,7 +557,7 @@ ParameterAnnotation* Collections::GenerateParameterAnnotation(
annotations->push_back(CreateAnnotationSetItem(dex_file, annotation_set_item, set_offset));
}
set_ref_list = new AnnotationSetRefList(annotations);
- annotation_set_ref_lists_.AddItem(set_ref_list, offset);
+ AddItem(annotation_set_ref_lists_map_, annotation_set_ref_lists_, set_ref_list, offset);
}
return new ParameterAnnotation(method_id, set_ref_list);
}
@@ -566,13 +573,13 @@ CodeItem* Collections::CreateCodeItem(const DexFile& dex_file,
const uint8_t* debug_info_stream = dex_file.GetDebugInfoStream(&disk_code_item);
DebugInfoItem* debug_info = nullptr;
if (debug_info_stream != nullptr) {
- debug_info = debug_info_items_.GetExistingObject(disk_code_item.debug_info_off_);
+ debug_info = debug_info_items_map_.GetExistingObject(disk_code_item.debug_info_off_);
if (debug_info == nullptr) {
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);
- debug_info_items_.AddItem(debug_info, disk_code_item.debug_info_off_);
+ AddItem(debug_info_items_map_, debug_info_items_, debug_info, disk_code_item.debug_info_off_);
}
}
@@ -662,7 +669,7 @@ CodeItem* Collections::CreateCodeItem(const DexFile& dex_file,
CodeItem* code_item = new CodeItem(
registers_size, ins_size, outs_size, debug_info, insns_size, insns, tries, handler_list);
code_item->SetSize(size);
- code_items_.AddItem(code_item, offset);
+ AddItem(code_items_map_, code_items_, code_item, offset);
// Add "fixup" references to types, strings, methods, and fields.
// This is temporary, as we will probably want more detailed parsing of the
// instructions here.
@@ -690,7 +697,7 @@ MethodItem* Collections::GenerateMethodItem(const DexFile& dex_file, ClassDataIt
MethodId* method_id = GetMethodId(cdii.GetMemberIndex());
uint32_t access_flags = cdii.GetRawMemberAccessFlags();
const DexFile::CodeItem* disk_code_item = cdii.GetMethodCodeItem();
- CodeItem* code_item = code_items_.GetExistingObject(cdii.GetMethodCodeItemOffset());
+ CodeItem* code_item = code_items_map_.GetExistingObject(cdii.GetMethodCodeItemOffset());
DebugInfoItem* debug_info = nullptr;
if (disk_code_item != nullptr) {
if (code_item == nullptr) {
@@ -705,7 +712,7 @@ ClassData* Collections::CreateClassData(
const DexFile& dex_file, const uint8_t* encoded_data, uint32_t offset) {
// Read the fields and methods defined by the class, resolving the circular reference from those
// to classes by setting class at the same time.
- ClassData* class_data = class_datas_.GetExistingObject(offset);
+ ClassData* class_data = class_datas_map_.GetExistingObject(offset);
if (class_data == nullptr && encoded_data != nullptr) {
ClassDataItemIterator cdii(dex_file, encoded_data);
// Static fields.
@@ -735,7 +742,7 @@ ClassData* Collections::CreateClassData(
}
class_data = new ClassData(static_fields, instance_fields, direct_methods, virtual_methods);
class_data->SetSize(cdii.EndDataPointer() - encoded_data);
- class_datas_.AddItem(class_data, offset);
+ AddItem(class_datas_map_, class_datas_, class_data, offset);
}
return class_data;
}
@@ -771,10 +778,10 @@ void Collections::CreateCallSiteId(const DexFile& dex_file, uint32_t i) {
const DexFile::CallSiteIdItem& disk_call_site_id = dex_file.GetCallSiteId(i);
const uint8_t* disk_call_item_ptr = dex_file.Begin() + disk_call_site_id.data_off_;
EncodedArrayItem* call_site_item =
- CreateEncodedArrayItem(disk_call_item_ptr, disk_call_site_id.data_off_);
+ CreateEncodedArrayItem(dex_file, disk_call_item_ptr, disk_call_site_id.data_off_);
CallSiteId* call_site_id = new CallSiteId(call_site_item);
- call_site_ids_.AddIndexedItem(call_site_id, CallSiteIdsOffset() + i * CallSiteId::ItemSize(), i);
+ AddIndexedItem(call_site_ids_, call_site_id, CallSiteIdsOffset() + i * CallSiteId::ItemSize(), i);
}
void Collections::CreateMethodHandleItem(const DexFile& dex_file, uint32_t i) {
@@ -796,8 +803,23 @@ void Collections::CreateMethodHandleItem(const DexFile& dex_file, uint32_t i) {
field_or_method_id = GetFieldId(index);
}
MethodHandleItem* method_handle = new MethodHandleItem(type, field_or_method_id);
- method_handle_items_.AddIndexedItem(
- method_handle, MethodHandleItemsOffset() + i * MethodHandleItem::ItemSize(), i);
+ AddIndexedItem(method_handle_items_,
+ method_handle,
+ MethodHandleItemsOffset() + i * MethodHandleItem::ItemSize(),
+ i);
+}
+
+void Collections::SortVectorsByMapOrder() {
+ string_datas_map_.SortVectorByMapOrder(string_datas_);
+ type_lists_map_.SortVectorByMapOrder(type_lists_);
+ encoded_array_items_map_.SortVectorByMapOrder(encoded_array_items_);
+ annotation_items_map_.SortVectorByMapOrder(annotation_items_);
+ annotation_set_items_map_.SortVectorByMapOrder(annotation_set_items_);
+ annotation_set_ref_lists_map_.SortVectorByMapOrder(annotation_set_ref_lists_);
+ annotations_directory_items_map_.SortVectorByMapOrder(annotations_directory_items_);
+ debug_info_items_map_.SortVectorByMapOrder(debug_info_items_);
+ code_items_map_.SortVectorByMapOrder(code_items_);
+ class_datas_map_.SortVectorByMapOrder(class_datas_);
}
static uint32_t HeaderOffset(const dex_ir::Collections& collections ATTRIBUTE_UNUSED) {