Move dexanalyze experiments to their own file

Reduce how much code is in the main file.

Bug: 77721545
Test: test-art-host-gtest-dexanalyze_test
Change-Id: I03e00b954170ff2e602edaa2e019f96e54016ecf
diff --git a/tools/dexanalyze/Android.bp b/tools/dexanalyze/Android.bp
index 34aaaac..2754e64 100644
--- a/tools/dexanalyze/Android.bp
+++ b/tools/dexanalyze/Android.bp
@@ -18,7 +18,10 @@
     name: "dexanalyze-defaults",
     defaults: ["art_defaults"],
     host_supported: true,
-    srcs: ["dexanalyze.cc"],
+    srcs: [
+        "dexanalyze.cc",
+        "dexanalyze_experiments.cc",
+    ],
     target: {
         android: {
             shared_libs: ["libcutils"],
diff --git a/tools/dexanalyze/dexanalyze.cc b/tools/dexanalyze/dexanalyze.cc
index 75fa13c..a5f647c 100644
--- a/tools/dexanalyze/dexanalyze.cc
+++ b/tools/dexanalyze/dexanalyze.cc
@@ -20,6 +20,7 @@
 
 #include <android-base/file.h>
 
+#include "dexanalyze_experiments.h"
 #include "dex/code_item_accessors-inl.h"
 #include "dex/dex_file.h"
 #include "dex/dex_file_loader.h"
@@ -27,147 +28,6 @@
 
 namespace art {
 
-// An experiment a stateful visitor that runs on dex files. Results are cumulative.
-class Experiment {
- public:
-  virtual ~Experiment() {}
-  virtual void ProcessDexFile(const DexFile& dex_file) = 0;
-  virtual void Dump(std::ostream& os) const = 0;
-};
-
-class CountDexIndices : public Experiment {
- public:
-  void ProcessDexFile(const DexFile& dex_file) {
-    num_string_ids_ += dex_file.NumStringIds();
-    num_method_ids_ += dex_file.NumMethodIds();
-    num_field_ids_ += dex_file.NumFieldIds();
-    num_type_ids_ += dex_file.NumTypeIds();
-    num_class_defs_ += dex_file.NumClassDefs();
-    for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); ++class_def_index) {
-      const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
-      const uint8_t* class_data = dex_file.GetClassData(class_def);
-      if (class_data == nullptr) {
-        continue;
-      }
-      ClassDataItemIterator it(dex_file, class_data);
-      it.SkipAllFields();
-      std::set<size_t> unique_method_ids;
-      std::set<size_t> unique_string_ids;
-      while (it.HasNextMethod()) {
-        const DexFile::CodeItem* code_item = it.GetMethodCodeItem();
-        if (code_item != nullptr) {
-          CodeItemInstructionAccessor instructions(dex_file, code_item);
-          const uint16_t* code_ptr = instructions.Insns();
-          dex_code_bytes_ += instructions.InsnsSizeInCodeUnits() * sizeof(code_ptr[0]);
-          for (const DexInstructionPcPair& inst : instructions) {
-            switch (inst->Opcode()) {
-              case Instruction::CONST_STRING: {
-                const dex::StringIndex string_index(inst->VRegB_21c());
-                unique_string_ids.insert(string_index.index_);
-                ++num_string_ids_from_code_;
-                break;
-              }
-              case Instruction::CONST_STRING_JUMBO: {
-                const dex::StringIndex string_index(inst->VRegB_31c());
-                unique_string_ids.insert(string_index.index_);
-                ++num_string_ids_from_code_;
-                break;
-              }
-              // Invoke cases.
-              case Instruction::INVOKE_VIRTUAL:
-              case Instruction::INVOKE_VIRTUAL_RANGE: {
-                bool is_range = (inst->Opcode() == Instruction::INVOKE_VIRTUAL_RANGE);
-                uint32_t method_idx = is_range ? inst->VRegB_3rc() : inst->VRegB_35c();
-                if (dex_file.GetMethodId(method_idx).class_idx_ == class_def.class_idx_) {
-                  ++same_class_virtual_;
-                } else {
-                  ++other_class_virtual_;
-                  unique_method_ids.insert(method_idx);
-                }
-                break;
-              }
-              case Instruction::INVOKE_DIRECT:
-              case Instruction::INVOKE_DIRECT_RANGE: {
-                bool is_range = (inst->Opcode() == Instruction::INVOKE_DIRECT_RANGE);
-                uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
-                if (dex_file.GetMethodId(method_idx).class_idx_ == class_def.class_idx_) {
-                  ++same_class_direct_;
-                } else {
-                  ++other_class_direct_;
-                  unique_method_ids.insert(method_idx);
-                }
-                break;
-              }
-              case Instruction::INVOKE_STATIC:
-              case Instruction::INVOKE_STATIC_RANGE: {
-                bool is_range = (inst->Opcode() == Instruction::INVOKE_STATIC_RANGE);
-                uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
-                if (dex_file.GetMethodId(method_idx).class_idx_ == class_def.class_idx_) {
-                  ++same_class_static_;
-                } else {
-                  ++other_class_static_;
-                  unique_method_ids.insert(method_idx);
-                }
-                break;
-              }
-              default:
-                break;
-            }
-          }
-        }
-        it.Next();
-      }
-      DCHECK(!it.HasNext());
-      total_unique_method_idx_ += unique_method_ids.size();
-      total_unique_string_ids_ += unique_string_ids.size();
-    }
-  }
-
-  void Dump(std::ostream& os) const {
-    os << "Num string ids: " << num_string_ids_ << "\n";
-    os << "Num method ids: " << num_method_ids_ << "\n";
-    os << "Num field ids: " << num_field_ids_ << "\n";
-    os << "Num type ids: " << num_type_ids_ << "\n";
-    os << "Num class defs: " << num_class_defs_ << "\n";
-    os << "Same class direct: " << same_class_direct_ << "\n";
-    os << "Other class direct: " << other_class_direct_ << "\n";
-    os << "Same class virtual: " << same_class_virtual_ << "\n";
-    os << "Other class virtual: " << other_class_virtual_ << "\n";
-    os << "Same class static: " << same_class_static_ << "\n";
-    os << "Other class static: " << other_class_static_ << "\n";
-    os << "Num strings accessed from code: " << num_string_ids_from_code_ << "\n";
-    os << "Unique(per class) method ids accessed from code: " << total_unique_method_idx_ << "\n";
-    os << "Unique(per class) string ids accessed from code: " << total_unique_string_ids_ << "\n";
-    size_t same_class_total = same_class_direct_ + same_class_virtual_ + same_class_static_;
-    size_t other_class_total = other_class_direct_ + other_class_virtual_ + other_class_static_;
-    os << "Same class invoke: " << same_class_total << "\n";
-    os << "Other class invoke: " << other_class_total << "\n";
-    os << "Invokes from code: " << (same_class_total + other_class_total) << "\n";
-  }
-
- private:
-  // Total string ids loaded from dex code.
-  size_t num_string_ids_from_code_ = 0;
-  size_t total_unique_method_idx_ = 0;
-  size_t total_unique_string_ids_ = 0;
-
-  // Other dex ids.
-  size_t dex_code_bytes_ = 0;
-  size_t num_string_ids_ = 0;
-  size_t num_method_ids_ = 0;
-  size_t num_field_ids_ = 0;
-  size_t num_type_ids_ = 0;
-  size_t num_class_defs_ = 0;
-
-  // Invokes
-  size_t same_class_direct_ = 0;
-  size_t other_class_direct_ = 0;
-  size_t same_class_virtual_ = 0;
-  size_t other_class_virtual_ = 0;
-  size_t same_class_static_ = 0;
-  size_t other_class_static_ = 0;
-};
-
 class DexAnalyze {
   static const int kExitCodeUsageError = 1;
 
diff --git a/tools/dexanalyze/dexanalyze_experiments.cc b/tools/dexanalyze/dexanalyze_experiments.cc
new file mode 100644
index 0000000..e1f119d
--- /dev/null
+++ b/tools/dexanalyze/dexanalyze_experiments.cc
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "dexanalyze_experiments.h"
+#include "dex/code_item_accessors-inl.h"
+#include "dex/dex_instruction-inl.h"
+#include "dex/standard_dex_file.h"
+
+namespace art {
+
+void CountDexIndices::ProcessDexFile(const DexFile& dex_file) {
+  num_string_ids_ += dex_file.NumStringIds();
+  num_method_ids_ += dex_file.NumMethodIds();
+  num_field_ids_ += dex_file.NumFieldIds();
+  num_type_ids_ += dex_file.NumTypeIds();
+  num_class_defs_ += dex_file.NumClassDefs();
+  for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); ++class_def_index) {
+    const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
+    const uint8_t* class_data = dex_file.GetClassData(class_def);
+    if (class_data == nullptr) {
+      continue;
+    }
+    ClassDataItemIterator it(dex_file, class_data);
+    it.SkipAllFields();
+    std::set<size_t> unique_method_ids;
+    std::set<size_t> unique_string_ids;
+    while (it.HasNextMethod()) {
+      const DexFile::CodeItem* code_item = it.GetMethodCodeItem();
+      if (code_item != nullptr) {
+        CodeItemInstructionAccessor instructions(dex_file, code_item);
+        const uint16_t* code_ptr = instructions.Insns();
+        dex_code_bytes_ += instructions.InsnsSizeInCodeUnits() * sizeof(code_ptr[0]);
+        for (const DexInstructionPcPair& inst : instructions) {
+          switch (inst->Opcode()) {
+            case Instruction::CONST_STRING: {
+              const dex::StringIndex string_index(inst->VRegB_21c());
+              unique_string_ids.insert(string_index.index_);
+              ++num_string_ids_from_code_;
+              break;
+            }
+            case Instruction::CONST_STRING_JUMBO: {
+              const dex::StringIndex string_index(inst->VRegB_31c());
+              unique_string_ids.insert(string_index.index_);
+              ++num_string_ids_from_code_;
+              break;
+            }
+            // Invoke cases.
+            case Instruction::INVOKE_VIRTUAL:
+            case Instruction::INVOKE_VIRTUAL_RANGE: {
+              bool is_range = (inst->Opcode() == Instruction::INVOKE_VIRTUAL_RANGE);
+              uint32_t method_idx = is_range ? inst->VRegB_3rc() : inst->VRegB_35c();
+              if (dex_file.GetMethodId(method_idx).class_idx_ == class_def.class_idx_) {
+                ++same_class_virtual_;
+              } else {
+                ++other_class_virtual_;
+                unique_method_ids.insert(method_idx);
+              }
+              break;
+            }
+            case Instruction::INVOKE_DIRECT:
+            case Instruction::INVOKE_DIRECT_RANGE: {
+              bool is_range = (inst->Opcode() == Instruction::INVOKE_DIRECT_RANGE);
+              uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
+              if (dex_file.GetMethodId(method_idx).class_idx_ == class_def.class_idx_) {
+                ++same_class_direct_;
+              } else {
+                ++other_class_direct_;
+                unique_method_ids.insert(method_idx);
+              }
+              break;
+            }
+            case Instruction::INVOKE_STATIC:
+            case Instruction::INVOKE_STATIC_RANGE: {
+              bool is_range = (inst->Opcode() == Instruction::INVOKE_STATIC_RANGE);
+              uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
+              if (dex_file.GetMethodId(method_idx).class_idx_ == class_def.class_idx_) {
+                ++same_class_static_;
+              } else {
+                ++other_class_static_;
+                unique_method_ids.insert(method_idx);
+              }
+              break;
+            }
+            default:
+              break;
+          }
+        }
+      }
+      it.Next();
+    }
+    DCHECK(!it.HasNext());
+    total_unique_method_idx_ += unique_method_ids.size();
+    total_unique_string_ids_ += unique_string_ids.size();
+  }
+}
+
+void CountDexIndices::Dump(std::ostream& os) const {
+  os << "Num string ids: " << num_string_ids_ << "\n";
+  os << "Num method ids: " << num_method_ids_ << "\n";
+  os << "Num field ids: " << num_field_ids_ << "\n";
+  os << "Num type ids: " << num_type_ids_ << "\n";
+  os << "Num class defs: " << num_class_defs_ << "\n";
+  os << "Same class direct: " << same_class_direct_ << "\n";
+  os << "Other class direct: " << other_class_direct_ << "\n";
+  os << "Same class virtual: " << same_class_virtual_ << "\n";
+  os << "Other class virtual: " << other_class_virtual_ << "\n";
+  os << "Same class static: " << same_class_static_ << "\n";
+  os << "Other class static: " << other_class_static_ << "\n";
+  os << "Num strings accessed from code: " << num_string_ids_from_code_ << "\n";
+  os << "Unique(per class) method ids accessed from code: " << total_unique_method_idx_ << "\n";
+  os << "Unique(per class) string ids accessed from code: " << total_unique_string_ids_ << "\n";
+  size_t same_class_total = same_class_direct_ + same_class_virtual_ + same_class_static_;
+  size_t other_class_total = other_class_direct_ + other_class_virtual_ + other_class_static_;
+  os << "Same class invoke: " << same_class_total << "\n";
+  os << "Other class invoke: " << other_class_total << "\n";
+  os << "Invokes from code: " << (same_class_total + other_class_total) << "\n";
+}
+
+}  // namespace art
+
diff --git a/tools/dexanalyze/dexanalyze_experiments.h b/tools/dexanalyze/dexanalyze_experiments.h
new file mode 100644
index 0000000..5d0f51b
--- /dev/null
+++ b/tools/dexanalyze/dexanalyze_experiments.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_TOOLS_DEXANALYZE_DEXANALYZE_EXPERIMENTS_H_
+#define ART_TOOLS_DEXANALYZE_DEXANALYZE_EXPERIMENTS_H_
+
+#include <iosfwd>
+#include <set>
+
+namespace art {
+
+class DexFile;
+
+// An experiment a stateful visitor that runs on dex files. Results are cumulative.
+class Experiment {
+ public:
+  virtual ~Experiment() {}
+  virtual void ProcessDexFile(const DexFile& dex_file) = 0;
+  virtual void Dump(std::ostream& os) const = 0;
+};
+
+// Count numbers of dex indices.
+class CountDexIndices : public Experiment {
+ public:
+  void ProcessDexFile(const DexFile& dex_file);
+
+  void Dump(std::ostream& os) const;
+
+ private:
+  // Total string ids loaded from dex code.
+  size_t num_string_ids_from_code_ = 0;
+  size_t total_unique_method_idx_ = 0;
+  size_t total_unique_string_ids_ = 0;
+
+  // Other dex ids.
+  size_t dex_code_bytes_ = 0;
+  size_t num_string_ids_ = 0;
+  size_t num_method_ids_ = 0;
+  size_t num_field_ids_ = 0;
+  size_t num_type_ids_ = 0;
+  size_t num_class_defs_ = 0;
+
+  // Invokes
+  size_t same_class_direct_ = 0;
+  size_t other_class_direct_ = 0;
+  size_t same_class_virtual_ = 0;
+  size_t other_class_virtual_ = 0;
+  size_t same_class_static_ = 0;
+  size_t other_class_static_ = 0;
+};
+
+}  // namespace art
+
+#endif  // ART_TOOLS_DEXANALYZE_DEXANALYZE_EXPERIMENTS_H_
+