Separate DexIr building from constructors.
Move all the construction from DexFile out of the constructors of the
basic IR.
Bug: 29921113
Change-Id: I3f79c104ce7183ddde73f143c047061416009a54
Test: test-art-host-gtest
diff --git a/dexlayout/dexlayout.cc b/dexlayout/dexlayout.cc
index 0b31614..0d0b37a 100644
--- a/dexlayout/dexlayout.cc
+++ b/dexlayout/dexlayout.cc
@@ -30,7 +30,7 @@
#include <sstream>
#include <vector>
-#include "dex_ir.h"
+#include "dex_ir_builder.h"
#include "dex_file-inl.h"
#include "dex_instruction-inl.h"
#include "utils.h"
@@ -501,20 +501,33 @@
}
fprintf(out_file_, "annotations_off : %d (0x%06x)\n",
annotations_offset, annotations_offset);
- fprintf(out_file_, "class_data_off : %d (0x%06x)\n",
- class_def->GetClassData()->GetOffset(), class_def->GetClassData()->GetOffset());
+ if (class_def->GetClassData() == nullptr) {
+ fprintf(out_file_, "class_data_off : %d (0x%06x)\n", 0, 0);
+ } else {
+ fprintf(out_file_, "class_data_off : %d (0x%06x)\n",
+ class_def->GetClassData()->GetOffset(), class_def->GetClassData()->GetOffset());
+ }
// Fields and methods.
dex_ir::ClassData* class_data = class_def->GetClassData();
- if (class_data != nullptr) {
- fprintf(out_file_, "static_fields_size : %zu\n", class_data->StaticFields().size());
- fprintf(out_file_, "instance_fields_size: %zu\n", class_data->InstanceFields().size());
- fprintf(out_file_, "direct_methods_size : %zu\n", class_data->DirectMethods().size());
- fprintf(out_file_, "virtual_methods_size: %zu\n", class_data->VirtualMethods().size());
+ if (class_data != nullptr && class_data->StaticFields() != nullptr) {
+ fprintf(out_file_, "static_fields_size : %zu\n", class_data->StaticFields()->size());
} else {
fprintf(out_file_, "static_fields_size : 0\n");
+ }
+ if (class_data != nullptr && class_data->InstanceFields() != nullptr) {
+ fprintf(out_file_, "instance_fields_size: %zu\n", class_data->InstanceFields()->size());
+ } else {
fprintf(out_file_, "instance_fields_size: 0\n");
+ }
+ if (class_data != nullptr && class_data->DirectMethods() != nullptr) {
+ fprintf(out_file_, "direct_methods_size : %zu\n", class_data->DirectMethods()->size());
+ } else {
fprintf(out_file_, "direct_methods_size : 0\n");
+ }
+ if (class_data != nullptr && class_data->VirtualMethods() != nullptr) {
+ fprintf(out_file_, "virtual_methods_size: %zu\n", class_data->VirtualMethods()->size());
+ } else {
fprintf(out_file_, "virtual_methods_size: 0\n");
}
fprintf(out_file_, "\n");
@@ -524,12 +537,11 @@
* Dumps an annotation set item.
*/
static void DumpAnnotationSetItem(dex_ir::AnnotationSetItem* set_item) {
- if (set_item == nullptr || set_item->GetItems().size() == 0) {
+ if (set_item == nullptr || set_item->GetItems()->size() == 0) {
fputs(" empty-annotation-set\n", out_file_);
return;
}
- for (std::unique_ptr<dex_ir::AnnotationSetItem::AnnotationItem>& annotation :
- set_item->GetItems()) {
+ for (std::unique_ptr<dex_ir::AnnotationItem>& annotation : *set_item->GetItems()) {
if (annotation == nullptr) {
continue;
}
@@ -561,12 +573,9 @@
fprintf(out_file_, "Class #%d annotations:\n", idx);
dex_ir::AnnotationSetItem* class_set_item = annotations_directory->GetClassAnnotation();
- std::vector<std::unique_ptr<dex_ir::AnnotationsDirectoryItem::FieldAnnotation>>& fields =
- annotations_directory->GetFieldAnnotations();
- std::vector<std::unique_ptr<dex_ir::AnnotationsDirectoryItem::MethodAnnotation>>& methods =
- annotations_directory->GetMethodAnnotations();
- std::vector<std::unique_ptr<dex_ir::AnnotationsDirectoryItem::ParameterAnnotation>>& parameters =
- annotations_directory->GetParameterAnnotations();
+ dex_ir::FieldAnnotationVector* fields = annotations_directory->GetFieldAnnotations();
+ dex_ir::MethodAnnotationVector* methods = annotations_directory->GetMethodAnnotations();
+ dex_ir::ParameterAnnotationVector* parameters = annotations_directory->GetParameterAnnotations();
// Annotations on the class itself.
if (class_set_item != nullptr) {
@@ -575,34 +584,40 @@
}
// Annotations on fields.
- for (auto& field : fields) {
- const dex_ir::FieldId* field_id = field->GetFieldId();
- const uint32_t field_idx = field_id->GetOffset();
- const char* field_name = field_id->Name()->Data();
- fprintf(out_file_, "Annotations on field #%u '%s'\n", field_idx, field_name);
- DumpAnnotationSetItem(field->GetAnnotationSetItem());
+ if (fields != nullptr) {
+ for (auto& field : *fields) {
+ const dex_ir::FieldId* field_id = field->GetFieldId();
+ const uint32_t field_idx = field_id->GetOffset();
+ const char* field_name = field_id->Name()->Data();
+ fprintf(out_file_, "Annotations on field #%u '%s'\n", field_idx, field_name);
+ DumpAnnotationSetItem(field->GetAnnotationSetItem());
+ }
}
// Annotations on methods.
- for (auto& method : methods) {
- const dex_ir::MethodId* method_id = method->GetMethodId();
- const uint32_t method_idx = method_id->GetOffset();
- const char* method_name = method_id->Name()->Data();
- fprintf(out_file_, "Annotations on method #%u '%s'\n", method_idx, method_name);
- DumpAnnotationSetItem(method->GetAnnotationSetItem());
+ if (methods != nullptr) {
+ for (auto& method : *methods) {
+ const dex_ir::MethodId* method_id = method->GetMethodId();
+ const uint32_t method_idx = method_id->GetOffset();
+ const char* method_name = method_id->Name()->Data();
+ fprintf(out_file_, "Annotations on method #%u '%s'\n", method_idx, method_name);
+ DumpAnnotationSetItem(method->GetAnnotationSetItem());
+ }
}
// Annotations on method parameters.
- for (auto& parameter : parameters) {
- const dex_ir::MethodId* method_id = parameter->GetMethodId();
- const uint32_t method_idx = method_id->GetOffset();
- const char* method_name = method_id->Name()->Data();
- fprintf(out_file_, "Annotations on method #%u '%s' parameters\n", method_idx, method_name);
- uint32_t j = 0;
- for (auto& annotation : parameter->GetAnnotations()) {
- fprintf(out_file_, "#%u\n", j);
- DumpAnnotationSetItem(annotation.get());
- ++j;
+ if (parameters != nullptr) {
+ for (auto& parameter : *parameters) {
+ const dex_ir::MethodId* method_id = parameter->GetMethodId();
+ const uint32_t method_idx = method_id->GetOffset();
+ const char* method_name = method_id->Name()->Data();
+ fprintf(out_file_, "Annotations on method #%u '%s' parameters\n", method_idx, method_name);
+ uint32_t j = 0;
+ for (auto& annotation : *parameter->GetAnnotations()) {
+ fprintf(out_file_, "#%u\n", j);
+ DumpAnnotationSetItem(annotation.get());
+ ++j;
+ }
}
}
@@ -612,7 +627,7 @@
/*
* Dumps an interface that a class declares to implement.
*/
-static void DumpInterface(dex_ir::TypeId* type_item, int i) {
+static void DumpInterface(const dex_ir::TypeId* type_item, int i) {
const char* interface_name = type_item->GetStringId()->Data();
if (options_.output_format_ == kOutputPlain) {
fprintf(out_file_, " #%d : '%s'\n", i, interface_name);
@@ -1260,8 +1275,8 @@
}
while (it.HasNextVirtualMethod()) {
DumpCFG(dex_file,
- it.GetMemberIndex(),
- it.GetMethodCodeItem());
+ it.GetMemberIndex(),
+ it.GetMethodCodeItem());
it.Next();
}
}
@@ -1274,7 +1289,10 @@
* If "*last_package" is nullptr or does not match the current class' package,
* the value will be replaced with a newly-allocated string.
*/
-static void DumpClass(dex_ir::Header* header, int idx, char** last_package) {
+static void DumpClass(const DexFile* dex_file,
+ dex_ir::Header* header,
+ int idx,
+ char** last_package) {
dex_ir::ClassDef* class_def = header->ClassDefs()[idx].get();
// Omitting non-public class.
if (options_.exports_only_ && (class_def->GetAccessFlags() & kAccPublic) == 0) {
@@ -1290,7 +1308,7 @@
}
if (options_.show_cfg_) {
- DumpCFG(&header->GetDexFile(), idx);
+ DumpCFG(dex_file, idx);
return;
}
@@ -1368,10 +1386,12 @@
}
// Interfaces.
- std::vector<dex_ir::TypeId*>* interfaces = class_def->Interfaces();
- for (uint32_t i = 0; i < interfaces->size(); i++) {
- DumpInterface((*interfaces)[i], i);
- } // for
+ dex_ir::TypeIdVector* interfaces = class_def->Interfaces();
+ if (interfaces != nullptr) {
+ for (uint32_t i = 0; i < interfaces->size(); i++) {
+ DumpInterface((*interfaces)[i], i);
+ } // for
+ }
// Fields and methods.
dex_ir::ClassData* class_data = class_def->GetClassData();
@@ -1383,52 +1403,68 @@
if (options_.output_format_ == kOutputPlain) {
fprintf(out_file_, " Static fields -\n");
}
- std::vector<std::unique_ptr<dex_ir::FieldItem>>& static_fields = class_data->StaticFields();
- for (uint32_t i = 0; i < static_fields.size(); i++) {
- DumpSField(header,
- static_fields[i]->GetFieldId()->GetOffset(),
- static_fields[i]->GetAccessFlags(),
- i,
- i < static_values_size ? (*static_values)[i].get() : nullptr);
- } // for
+ if (class_data != nullptr) {
+ dex_ir::FieldItemVector* static_fields = class_data->StaticFields();
+ if (static_fields != nullptr) {
+ for (uint32_t i = 0; i < static_fields->size(); i++) {
+ DumpSField(header,
+ (*static_fields)[i]->GetFieldId()->GetOffset(),
+ (*static_fields)[i]->GetAccessFlags(),
+ i,
+ i < static_values_size ? (*static_values)[i].get() : nullptr);
+ } // for
+ }
+ }
// Instance fields.
if (options_.output_format_ == kOutputPlain) {
fprintf(out_file_, " Instance fields -\n");
}
- std::vector<std::unique_ptr<dex_ir::FieldItem>>& instance_fields = class_data->InstanceFields();
- for (uint32_t i = 0; i < instance_fields.size(); i++) {
- DumpIField(header,
- instance_fields[i]->GetFieldId()->GetOffset(),
- instance_fields[i]->GetAccessFlags(),
- i);
- } // for
+ if (class_data != nullptr) {
+ dex_ir::FieldItemVector* instance_fields = class_data->InstanceFields();
+ if (instance_fields != nullptr) {
+ for (uint32_t i = 0; i < instance_fields->size(); i++) {
+ DumpIField(header,
+ (*instance_fields)[i]->GetFieldId()->GetOffset(),
+ (*instance_fields)[i]->GetAccessFlags(),
+ i);
+ } // for
+ }
+ }
// Direct methods.
if (options_.output_format_ == kOutputPlain) {
fprintf(out_file_, " Direct methods -\n");
}
- std::vector<std::unique_ptr<dex_ir::MethodItem>>& direct_methods = class_data->DirectMethods();
- for (uint32_t i = 0; i < direct_methods.size(); i++) {
- DumpMethod(header,
- direct_methods[i]->GetMethodId()->GetOffset(),
- direct_methods[i]->GetAccessFlags(),
- direct_methods[i]->GetCodeItem(),
- i);
- } // for
+ if (class_data != nullptr) {
+ dex_ir::MethodItemVector* direct_methods = class_data->DirectMethods();
+ if (direct_methods != nullptr) {
+ for (uint32_t i = 0; i < direct_methods->size(); i++) {
+ DumpMethod(header,
+ (*direct_methods)[i]->GetMethodId()->GetOffset(),
+ (*direct_methods)[i]->GetAccessFlags(),
+ (*direct_methods)[i]->GetCodeItem(),
+ i);
+ } // for
+ }
+ }
// Virtual methods.
if (options_.output_format_ == kOutputPlain) {
fprintf(out_file_, " Virtual methods -\n");
}
- std::vector<std::unique_ptr<dex_ir::MethodItem>>& virtual_methods = class_data->VirtualMethods();
- for (uint32_t i = 0; i < virtual_methods.size(); i++) {
- DumpMethod(header,
- virtual_methods[i]->GetMethodId()->GetOffset(),
- virtual_methods[i]->GetAccessFlags(),
- virtual_methods[i]->GetCodeItem(),
- i);
- } // for
+ if (class_data != nullptr) {
+ dex_ir::MethodItemVector* virtual_methods = class_data->VirtualMethods();
+ if (virtual_methods != nullptr) {
+ for (uint32_t i = 0; i < virtual_methods->size(); i++) {
+ DumpMethod(header,
+ (*virtual_methods)[i]->GetMethodId()->GetOffset(),
+ (*virtual_methods)[i]->GetAccessFlags(),
+ (*virtual_methods)[i]->GetCodeItem(),
+ i);
+ } // for
+ }
+ }
// End of class.
if (options_.output_format_ == kOutputPlain) {
@@ -1454,11 +1490,11 @@
fprintf(out_file_, "Opened '%s', DEX version '%.3s'\n",
file_name, dex_file->GetHeader().magic_ + 4);
}
- dex_ir::Header header(*dex_file);
+ dex_ir::Header* header = dex_ir::DexIrBuilder(*dex_file);
// Headers.
if (options_.show_file_headers_) {
- DumpFileHeader(&header);
+ DumpFileHeader(header);
}
// Open XML context.
@@ -1468,9 +1504,9 @@
// Iterate over all classes.
char* package = nullptr;
- const uint32_t class_defs_size = header.ClassDefsSize();
+ const uint32_t class_defs_size = header->ClassDefsSize();
for (uint32_t i = 0; i < class_defs_size; i++) {
- DumpClass(&header, i, &package);
+ DumpClass(dex_file, header, i, &package);
} // for
// Free the last package allocated.