Count unique string, method names, and type names
Sample results (per APK):
Unique method names: 1385861(15.03%)
Unique field names: 1986979(16.25%)
Unique type names: 1944509(78.46%)
Bug: 77721545
Test: test-art-host
Change-Id: I4c809aed5d5ca9d8e81f113955b3430a673d67f2
diff --git a/tools/dexanalyze/dexanalyze_experiments.cc b/tools/dexanalyze/dexanalyze_experiments.cc
index 5299c9e..d4e3f1f 100644
--- a/tools/dexanalyze/dexanalyze_experiments.cc
+++ b/tools/dexanalyze/dexanalyze_experiments.cc
@@ -280,6 +280,33 @@
os << "Prefix dictionary elements " << total_num_prefixes_ << "\n";
}
+void CountDexIndices::ProcessDexFiles(
+ const std::vector<std::unique_ptr<const DexFile>>& dex_files) {
+ std::set<std::string> unique_field_names;
+ std::set<std::string> unique_method_names;
+ std::set<std::string> unique_type_names;
+ std::set<std::string> unique_mf_names;
+ for (const std::unique_ptr<const DexFile>& dex_file : dex_files) {
+ for (size_t i = 0; i < dex_file->NumTypeIds(); ++i) {
+ unique_type_names.insert(
+ dex_file->StringDataByIdx(dex_file->GetTypeId(dex::TypeIndex(i)).descriptor_idx_));
+ }
+ for (size_t i = 0; i < dex_file->NumFieldIds(); ++i) {
+ unique_field_names.insert(dex_file->StringDataByIdx(dex_file->GetFieldId(i).name_idx_));
+ }
+ for (size_t i = 0; i < dex_file->NumMethodIds(); ++i) {
+ unique_method_names.insert(dex_file->StringDataByIdx(dex_file->GetMethodId(i).name_idx_));
+ }
+ ProcessDexFile(*dex_file);
+ }
+ total_unique_method_names_ += unique_method_names.size();
+ total_unique_field_names_ += unique_field_names.size();
+ total_unique_type_names_ += unique_type_names.size();
+ unique_mf_names = unique_field_names;
+ unique_mf_names.insert(unique_method_names.begin(), unique_method_names.end());
+ total_unique_mf_names_ += unique_mf_names.size();
+}
+
void CountDexIndices::ProcessDexFile(const DexFile& dex_file) {
num_string_ids_ += dex_file.NumStringIds();
num_method_ids_ += dex_file.NumMethodIds();
@@ -287,6 +314,7 @@
num_type_ids_ += dex_file.NumTypeIds();
num_class_defs_ += dex_file.NumClassDefs();
std::set<size_t> unique_code_items;
+
for (ClassAccessor accessor : dex_file.GetClasses()) {
std::set<size_t> unique_method_ids;
std::set<size_t> unique_string_ids;
@@ -494,6 +522,11 @@
total_static_ +
total_interface_ +
total_super_;
+ os << "Unique method names: " << Percent(total_unique_method_names_, num_field_ids_) << "\n";
+ os << "Unique field names: " << Percent(total_unique_field_names_, num_method_ids_) << "\n";
+ os << "Unique type names: " << Percent(total_unique_type_names_, num_type_ids_) << "\n";
+ os << "Unique method/field names: "
+ << Percent(total_unique_mf_names_, num_field_ids_ + num_method_ids_) << "\n";
os << "Same class invokes: " << PercentDivide(same_class_total, other_class_total) << "\n";
os << "Invokes from code: " << (same_class_total + other_class_total) << "\n";
os << "Type uses on top types: " << PercentDivide(uses_top_types_, uses_all_types_) << "\n";
diff --git a/tools/dexanalyze/dexanalyze_experiments.h b/tools/dexanalyze/dexanalyze_experiments.h
index d3a9c59..0cafe27 100644
--- a/tools/dexanalyze/dexanalyze_experiments.h
+++ b/tools/dexanalyze/dexanalyze_experiments.h
@@ -23,6 +23,8 @@
#include <set>
#include <vector>
+#include "base/macros.h"
+
namespace art {
class DexFile;
@@ -41,8 +43,8 @@
// Analyze string data and strings accessed from code.
class AnalyzeStrings : public Experiment {
public:
- void ProcessDexFile(const DexFile& dex_file);
- void Dump(std::ostream& os, uint64_t total_size) const;
+ void ProcessDexFile(const DexFile& dex_file) OVERRIDE;
+ void Dump(std::ostream& os, uint64_t total_size) const OVERRIDE;
private:
int64_t wide_string_bytes_ = 0u;
@@ -58,8 +60,8 @@
// Analyze debug info sizes.
class AnalyzeDebugInfo : public Experiment {
public:
- void ProcessDexFiles(const std::vector<std::unique_ptr<const DexFile>>& dex_files);
- void Dump(std::ostream& os, uint64_t total_size) const;
+ void ProcessDexFiles(const std::vector<std::unique_ptr<const DexFile>>& dex_files) OVERRIDE;
+ void Dump(std::ostream& os, uint64_t total_size) const OVERRIDE;
private:
int64_t total_bytes_ = 0u;
@@ -84,7 +86,8 @@
// Count numbers of dex indices.
class CountDexIndices : public Experiment {
public:
- void ProcessDexFile(const DexFile& dex_file);
+ void ProcessDexFile(const DexFile& dex_file) OVERRIDE;
+ void ProcessDexFiles(const std::vector<std::unique_ptr<const DexFile>>& dex_files) OVERRIDE;
void Dump(std::ostream& os, uint64_t total_size) const;
@@ -101,6 +104,12 @@
uint64_t field_receiver_[16] = {};
uint64_t field_output_[16] = {};
+ // Unique names.
+ uint64_t total_unique_method_names_ = 0u;
+ uint64_t total_unique_field_names_ = 0u;
+ uint64_t total_unique_type_names_ = 0u;
+ uint64_t total_unique_mf_names_ = 0u;
+
// Other dex ids.
size_t dex_code_bytes_ = 0;
size_t num_string_ids_ = 0;
@@ -130,9 +139,9 @@
// Measure various code metrics including args per invoke-virtual, fill/spill move patterns.
class CodeMetrics : public Experiment {
public:
- void ProcessDexFile(const DexFile& dex_file);
+ void ProcessDexFile(const DexFile& dex_file) OVERRIDE;
- void Dump(std::ostream& os, uint64_t total_size) const;
+ void Dump(std::ostream& os, uint64_t total_size) const OVERRIDE;
private:
static constexpr size_t kMaxArgCount = 6;