/*
 * 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 <algorithm>
#include <stdint.h>
#include <inttypes.h>
#include <iostream>
#include <map>
#include <vector>

#include "android-base/stringprintf.h"
#include "dex/class_accessor-inl.h"
#include "dex/class_iterator.h"
#include "dex/code_item_accessors-inl.h"
#include "dex/dex_instruction-inl.h"
#include "dex/standard_dex_file.h"
#include "dex/utf-inl.h"

namespace art {
namespace dexanalyze {

bool IsRange(Instruction::Code code) {
  return code == Instruction::INVOKE_VIRTUAL_RANGE ||
      code == Instruction::INVOKE_DIRECT_RANGE ||
      code == Instruction::INVOKE_SUPER_RANGE ||
      code == Instruction::INVOKE_STATIC_RANGE ||
      code == Instruction::INVOKE_INTERFACE_RANGE;
}

uint16_t NumberOfArgs(const Instruction& inst) {
  return IsRange(inst.Opcode()) ? inst.VRegA_3rc() : inst.VRegA_35c();
}

uint16_t DexMethodIndex(const Instruction& inst) {
  return IsRange(inst.Opcode()) ? inst.VRegB_3rc() : inst.VRegB_35c();
}

std::string Percent(uint64_t value, uint64_t max) {
  if (max == 0) {
    return "0";
  }
  return android::base::StringPrintf(
      "%" PRId64 "(%.2f%%)",
      value,
      static_cast<double>(value * 100) / static_cast<double>(max));
}

std::string PercentDivide(uint64_t value, uint64_t max) {
  if (max == 0) {
    return "0";
  }
  return android::base::StringPrintf(
      "%" PRId64 "/%" PRId64 "(%.2f%%)",
      value,
      max,
      static_cast<double>(value * 100) / static_cast<double>(max));
}

size_t PrefixLen(const std::string& a, const std::string& b) {
  size_t len = 0;
  for (; len < a.length() && len < b.length() && a[len] == b[len]; ++len) {}
  return len;
}

void Experiment::ProcessDexFiles(const std::vector<std::unique_ptr<const DexFile>>& dex_files) {
  for (const std::unique_ptr<const DexFile>& dex_file : dex_files) {
    ProcessDexFile(*dex_file);
  }
}

void AnalyzeDebugInfo::ProcessDexFiles(
    const std::vector<std::unique_ptr<const DexFile>>& dex_files) {
  std::set<const uint8_t*> seen;
  std::vector<size_t> counts(256, 0u);
  std::vector<size_t> opcode_counts(256, 0u);
  std::set<std::vector<uint8_t>> unique_non_header;
  for (const std::unique_ptr<const DexFile>& dex_file : dex_files) {
    for (ClassAccessor accessor : dex_file->GetClasses()) {
      for (const ClassAccessor::Method& method : accessor.GetMethods()) {
        CodeItemDebugInfoAccessor code_item(*dex_file, method.GetCodeItem(), method.GetIndex());
        const uint8_t* debug_info = dex_file->GetDebugInfoStream(code_item.DebugInfoOffset());
        if (debug_info != nullptr && seen.insert(debug_info).second) {
          const uint8_t* stream = debug_info;
          DecodeUnsignedLeb128(&stream);  // line_start
          uint32_t parameters_size = DecodeUnsignedLeb128(&stream);
          for (uint32_t i = 0; i < parameters_size; ++i) {
            DecodeUnsignedLeb128P1(&stream);  // Parameter name.
          }
          bool done = false;
          const uint8_t* after_header_start = stream;
          while (!done) {
            const uint8_t* const op_start = stream;
            uint8_t opcode = *stream++;
            ++opcode_counts[opcode];
            ++total_opcode_bytes_;
            switch (opcode) {
              case DexFile::DBG_END_SEQUENCE:
                ++total_end_seq_bytes_;
                done = true;
                break;
              case DexFile::DBG_ADVANCE_PC:
                DecodeUnsignedLeb128(&stream);  // addr_diff
                total_advance_pc_bytes_ += stream - op_start;
                break;
              case DexFile::DBG_ADVANCE_LINE:
                DecodeSignedLeb128(&stream);  // line_diff
                total_advance_line_bytes_ += stream - op_start;
                break;
              case DexFile::DBG_START_LOCAL:
                DecodeUnsignedLeb128(&stream);  // register_num
                DecodeUnsignedLeb128P1(&stream);  // name_idx
                DecodeUnsignedLeb128P1(&stream);  // type_idx
                total_start_local_bytes_ += stream - op_start;
                break;
              case DexFile::DBG_START_LOCAL_EXTENDED:
                DecodeUnsignedLeb128(&stream);  // register_num
                DecodeUnsignedLeb128P1(&stream);  // name_idx
                DecodeUnsignedLeb128P1(&stream);  // type_idx
                DecodeUnsignedLeb128P1(&stream);  // sig_idx
                total_start_local_extended_bytes_ += stream - op_start;
                break;
              case DexFile::DBG_END_LOCAL:
                DecodeUnsignedLeb128(&stream);  // register_num
                total_end_local_bytes_ += stream - op_start;
                break;
              case DexFile::DBG_RESTART_LOCAL:
                DecodeUnsignedLeb128(&stream);  // register_num
                total_restart_local_bytes_ += stream - op_start;
                break;
              case DexFile::DBG_SET_PROLOGUE_END:
              case DexFile::DBG_SET_EPILOGUE_BEGIN:
                total_epilogue_bytes_ += stream - op_start;
                break;
              case DexFile::DBG_SET_FILE: {
                DecodeUnsignedLeb128P1(&stream);  // name_idx
                total_set_file_bytes_ += stream - op_start;
                break;
              }
              default: {
                total_other_bytes_ += stream - op_start;
                break;
              }
            }
          }
          const size_t bytes = stream - debug_info;
          total_bytes_ += bytes;
          total_non_header_bytes_ += stream - after_header_start;
          if (unique_non_header.insert(std::vector<uint8_t>(after_header_start, stream)).second) {
            total_unique_non_header_bytes_ += stream - after_header_start;
          }
          for (size_t i = 0; i < bytes; ++i) {
            ++counts[debug_info[i]];
          }
        }
      }
    }
  }
  auto calc_entropy = [](std::vector<size_t> data) {
    size_t total = std::accumulate(data.begin(), data.end(), 0u);
    double avg_entropy = 0.0;
    for (size_t c : data) {
      if (c > 0) {
        double ratio = static_cast<double>(c) / static_cast<double>(total);
        avg_entropy -= ratio * log(ratio) / log(256.0);
      }
    }
    return avg_entropy * total;
  };
  total_entropy_ += calc_entropy(counts);
  total_opcode_entropy_ += calc_entropy(opcode_counts);
}

void AnalyzeDebugInfo::Dump(std::ostream& os, uint64_t total_size) const {
  os << "Debug info bytes " << Percent(total_bytes_, total_size) << "\n";

  os << "  DBG_END_SEQUENCE: " << Percent(total_end_seq_bytes_, total_size) << "\n";
  os << "  DBG_ADVANCE_PC: " << Percent(total_advance_pc_bytes_, total_size) << "\n";
  os << "  DBG_ADVANCE_LINE: " << Percent(total_advance_line_bytes_, total_size) << "\n";
  os << "  DBG_START_LOCAL: " << Percent(total_start_local_bytes_, total_size) << "\n";
  os << "  DBG_START_LOCAL_EXTENDED: "
     << Percent(total_start_local_extended_bytes_, total_size) << "\n";
  os << "  DBG_END_LOCAL: " << Percent(total_end_local_bytes_, total_size) << "\n";
  os << "  DBG_RESTART_LOCAL: " << Percent(total_restart_local_bytes_, total_size) << "\n";
  os << "  DBG_SET_PROLOGUE bytes " << Percent(total_epilogue_bytes_, total_size) << "\n";
  os << "  DBG_SET_FILE bytes " << Percent(total_set_file_bytes_, total_size) << "\n";
  os << "  special: "
      << Percent(total_other_bytes_, total_size) << "\n";
  os << "Debug info entropy " << Percent(total_entropy_, total_size) << "\n";
  os << "Debug info opcode bytes " << Percent(total_opcode_bytes_, total_size) << "\n";
  os << "Debug info opcode entropy " << Percent(total_opcode_entropy_, total_size) << "\n";
  os << "Debug info non header bytes " << Percent(total_non_header_bytes_, total_size) << "\n";
  os << "Debug info deduped non header bytes "
     << Percent(total_unique_non_header_bytes_, total_size) << "\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();
  num_field_ids_ += dex_file.NumFieldIds();
  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;
    // Types accessed and count.
    std::map<size_t, size_t> types_accessed;

    // Maps from dex field index -> class field index (static or instance).
    std::map<uint32_t, uint32_t> static_field_index_map_;
    size_t current_idx = 0u;
    for (const ClassAccessor::Field& field : accessor.GetStaticFields()) {
      static_field_index_map_[field.GetIndex()] = current_idx++;
    }
    std::map<uint32_t, uint32_t> instance_field_index_map_;
    current_idx = 0u;
    for (const ClassAccessor::Field& field : accessor.GetInstanceFields()) {
      instance_field_index_map_[field.GetIndex()] = current_idx++;
    }
    auto ProcessFieldIndex = [&](uint32_t dex_field_idx,
                                 uint32_t inout,
                                 const std::map<uint32_t, uint32_t>& index_map,
                                 /*inout*/ FieldAccessStats* stats) {
      auto it = index_map.find(dex_field_idx);
      if (it != index_map.end()) {
        if (it->second < FieldAccessStats::kMaxFieldIndex) {
          ++stats->field_index_[it->second];
        } else {
          ++stats->field_index_other_;
        }
      } else {
        ++stats->field_index_other_class_;
      }
      if (it != index_map.end() &&
          it->second < FieldAccessStats::kShortBytecodeFieldIndexOutCutOff &&
          inout < FieldAccessStats::kShortBytecodeInOutCutOff) {
        ++stats->short_bytecode_;
      }
    };
    auto ProcessInstanceField = [&](const Instruction& inst,
                                    uint32_t first_arg_reg,
                                    const std::map<uint32_t, uint32_t>& index_map,
                                    /*inout*/ InstanceFieldAccessStats* stats) {
      const uint32_t dex_field_idx = inst.VRegC_22c();
      ++types_accessed[dex_file.GetFieldId(dex_field_idx).class_idx_.index_];
      uint32_t input = inst.VRegA_22c();
      ++stats->inout_[input];
      const uint32_t receiver = inst.VRegB_22c();
      // FIXME: This is weird if receiver < first_arg_reg.
      ++stats->receiver_[(receiver - first_arg_reg) & 0xF];
      if (first_arg_reg == receiver) {
        ProcessFieldIndex(dex_field_idx, input, index_map, stats);
      }
    };
    auto ProcessStaticField = [&](const Instruction& inst,
                                  const std::map<uint32_t, uint32_t>& index_map,
                                  /*inout*/ StaticFieldAccessStats* stats) {
      const uint32_t dex_field_idx = inst.VRegB_21c();
      ++types_accessed[dex_file.GetFieldId(dex_field_idx).class_idx_.index_];
      uint8_t output = inst.VRegA_21c();
      if (output < 16u) {
        ++stats->inout_[output];
      } else {
        ++stats->inout_other_;
      }
      ProcessFieldIndex(dex_field_idx, output, index_map, stats);
    };

    for (const ClassAccessor::Method& method : accessor.GetMethods()) {
      CodeItemDataAccessor code_item(dex_file, method.GetCodeItem());
      const uint32_t first_arg_reg =
          ((method.GetAccessFlags() & kAccStatic) == 0)
          ? code_item.RegistersSize() - code_item.InsSize()
          : static_cast<uint32_t>(-1);

      dex_code_bytes_ += code_item.InsnsSizeInBytes();
      unique_code_items.insert(method.GetCodeItemOffset());
      for (const DexInstructionPcPair& inst : code_item) {
        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::IGET:
          case Instruction::IGET_WIDE:
          case Instruction::IGET_OBJECT:
          case Instruction::IGET_BOOLEAN:
          case Instruction::IGET_BYTE:
          case Instruction::IGET_CHAR:
          case Instruction::IGET_SHORT: {
            ProcessInstanceField(
                inst.Inst(), first_arg_reg, instance_field_index_map_, &iget_stats_);
            break;
          }
          case Instruction::IPUT:
          case Instruction::IPUT_WIDE:
          case Instruction::IPUT_OBJECT:
          case Instruction::IPUT_BOOLEAN:
          case Instruction::IPUT_BYTE:
          case Instruction::IPUT_CHAR:
          case Instruction::IPUT_SHORT: {
            ProcessInstanceField(
                inst.Inst(), first_arg_reg, instance_field_index_map_, &iput_stats_);
            break;
          }
          case Instruction::SGET:
          case Instruction::SGET_WIDE:
          case Instruction::SGET_OBJECT:
          case Instruction::SGET_BOOLEAN:
          case Instruction::SGET_BYTE:
          case Instruction::SGET_CHAR:
          case Instruction::SGET_SHORT: {
            ProcessStaticField(inst.Inst(), static_field_index_map_, &sget_stats_);
            break;
          }
          case Instruction::SPUT:
          case Instruction::SPUT_WIDE:
          case Instruction::SPUT_OBJECT:
          case Instruction::SPUT_BOOLEAN:
          case Instruction::SPUT_BYTE:
          case Instruction::SPUT_CHAR:
          case Instruction::SPUT_SHORT: {
            ProcessStaticField(inst.Inst(), static_field_index_map_, &sput_stats_);
            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: {
            uint32_t method_idx = DexMethodIndex(inst.Inst());
            ++types_accessed[dex_file.GetMethodId(method_idx).class_idx_.index_];
            if (dex_file.GetMethodId(method_idx).class_idx_ == accessor.GetClassIdx()) {
              ++same_class_virtual_;
            }
            ++total_virtual_;
            unique_method_ids.insert(method_idx);
            break;
          }
          case Instruction::INVOKE_DIRECT:
          case Instruction::INVOKE_DIRECT_RANGE: {
            uint32_t method_idx = DexMethodIndex(inst.Inst());
            ++types_accessed[dex_file.GetMethodId(method_idx).class_idx_.index_];
            if (dex_file.GetMethodId(method_idx).class_idx_ == accessor.GetClassIdx()) {
              ++same_class_direct_;
            }
            ++total_direct_;
            unique_method_ids.insert(method_idx);
            break;
          }
          case Instruction::INVOKE_STATIC:
          case Instruction::INVOKE_STATIC_RANGE: {
            uint32_t method_idx = DexMethodIndex(inst.Inst());
            ++types_accessed[dex_file.GetMethodId(method_idx).class_idx_.index_];
            if (dex_file.GetMethodId(method_idx).class_idx_ == accessor.GetClassIdx()) {
              ++same_class_static_;
            }
            ++total_static_;
            unique_method_ids.insert(method_idx);
            break;
          }
          case Instruction::INVOKE_INTERFACE:
          case Instruction::INVOKE_INTERFACE_RANGE: {
            uint32_t method_idx = DexMethodIndex(inst.Inst());
            ++types_accessed[dex_file.GetMethodId(method_idx).class_idx_.index_];
            if (dex_file.GetMethodId(method_idx).class_idx_ == accessor.GetClassIdx()) {
              ++same_class_interface_;
            }
            ++total_interface_;
            unique_method_ids.insert(method_idx);
            break;
          }
          case Instruction::INVOKE_SUPER:
          case Instruction::INVOKE_SUPER_RANGE: {
            uint32_t method_idx = DexMethodIndex(inst.Inst());
            ++types_accessed[dex_file.GetMethodId(method_idx).class_idx_.index_];
            if (dex_file.GetMethodId(method_idx).class_idx_ == accessor.GetClassIdx()) {
              ++same_class_super_;
            }
            ++total_super_;
            unique_method_ids.insert(method_idx);
            break;
          }
          case Instruction::NEW_ARRAY: {
            ++types_accessed[inst->VRegC_22c()];
            break;
          }
          case Instruction::FILLED_NEW_ARRAY: {
            ++types_accessed[inst->VRegB_35c()];
            break;
          }
          case Instruction::FILLED_NEW_ARRAY_RANGE: {
            ++types_accessed[inst->VRegB_3rc()];
            break;
          }
          case Instruction::CONST_CLASS:
          case Instruction::CHECK_CAST:
          case Instruction::NEW_INSTANCE: {
            ++types_accessed[inst->VRegB_21c()];
            break;
          }
          case Instruction::INSTANCE_OF: {
            ++types_accessed[inst->VRegB_21c()];
            break;
          }
          default:
            break;
        }
      }
    }
    // Count uses of top 16n.
    std::vector<size_t> uses;
    uses.reserve(types_accessed.size());
    for (auto&& p : types_accessed) {
      uses.push_back(p.second);
    }
    std::sort(uses.rbegin(), uses.rend());
    for (size_t i = 0; i < uses.size(); ++i) {
      if (i < 16) {
        uses_top_types_ += uses[i];
      }
      uses_all_types_ += uses[i];
    }
    total_unique_types_ += types_accessed.size();
    total_unique_method_ids_ += unique_method_ids.size();
    total_unique_string_ids_ += unique_string_ids.size();
  }
  total_unique_code_items_ += unique_code_items.size();
}

void CountDexIndices::Dump(std::ostream& os, uint64_t total_size) const {
  auto DumpFieldIndexes = [&](const FieldAccessStats& stats) {
    const uint64_t fields_idx_total = std::accumulate(
        stats.field_index_,
        stats.field_index_ + FieldAccessStats::kMaxFieldIndex,
        stats.field_index_other_ + stats.field_index_other_class_);
    for (size_t i = 0; i < FieldAccessStats::kMaxFieldIndex; ++i) {
      os << "  field_idx=" << i << ": " << Percent(stats.field_index_[i], fields_idx_total) << "\n";
    }
    os << "  field_idx=other: " << Percent(stats.field_index_other_, fields_idx_total) << "\n";
    os << "  field_idx=other_class: " << Percent(stats.field_index_other_class_, fields_idx_total)
       << "\n";
  };
  auto DumpInstanceFieldStats = [&](const char* tag, const InstanceFieldAccessStats& stats) {
    const uint64_t fields_total = std::accumulate(stats.inout_, stats.inout_ + 16u, 0u);
    os << tag << "\n";
    for (size_t i = 0; i < 16; ++i) {
      os << "  receiver_reg=" << i << ": " << Percent(stats.receiver_[i], fields_total) << "\n";
    }
    DCHECK(tag[1] == 'G' || tag[1] == 'P');
    const char* inout_tag = (tag[1] == 'G') ? "output_reg" : "input_reg";
    for (size_t i = 0; i < 16; ++i) {
      os << "  " << inout_tag << "=" << i << ": " << Percent(stats.inout_[i], fields_total) << "\n";
    }
    DumpFieldIndexes(stats);
    os << "  short_bytecode: " << Percent(stats.short_bytecode_, fields_total) << "\n";
    os << "  short_bytecode_savings=" << Percent(stats.short_bytecode_ * 2, total_size) << "\n";
  };
  DumpInstanceFieldStats("IGET", iget_stats_);
  DumpInstanceFieldStats("IPUT", iput_stats_);

  auto DumpStaticFieldStats = [&](const char* tag, const StaticFieldAccessStats& stats) {
    const uint64_t fields_total =
        std::accumulate(stats.inout_, stats.inout_ + 16u, stats.inout_other_);
    os << tag << "\n";
    DCHECK(tag[1] == 'G' || tag[1] == 'P');
    const char* inout_tag = (tag[1] == 'G') ? "output_reg" : "input_reg";
    for (size_t i = 0; i < 16; ++i) {
      os << "  " << inout_tag << "=" << i << ": " << Percent(stats.inout_[i], fields_total) << "\n";
    }
    os << "  " << inout_tag << "=other: " << Percent(stats.inout_other_, fields_total) << "\n";
    DumpFieldIndexes(stats);
    os << "  short_bytecode: " << Percent(stats.short_bytecode_, fields_total) << "\n";
    os << "  short_bytecode_savings=" << Percent(stats.short_bytecode_ * 2, total_size) << "\n";
  };
  DumpStaticFieldStats("SGET", sget_stats_);
  DumpStaticFieldStats("SPUT", sput_stats_);

  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 << "Direct same class: " << PercentDivide(same_class_direct_, total_direct_) << "\n";
  os << "Virtual same class: " << PercentDivide(same_class_virtual_, total_virtual_) << "\n";
  os << "Static same class: " << PercentDivide(same_class_static_, total_static_) << "\n";
  os << "Interface same class: " << PercentDivide(same_class_interface_, total_interface_) << "\n";
  os << "Super same class: " << PercentDivide(same_class_super_, total_super_) << "\n";
  os << "Num strings accessed from code: " << num_string_ids_from_code_ << "\n";
  os << "Avg unique methods accessed per class: "
     << static_cast<double>(total_unique_method_ids_) / static_cast<double>(num_class_defs_) << "\n";
  os << "Avg unique strings accessed per class: "
     << static_cast<double>(total_unique_string_ids_) / static_cast<double>(num_class_defs_) << "\n";
  os << "Avg unique types accessed per class " <<
        static_cast<double>(total_unique_types_) / static_cast<double>(num_class_defs_) << "\n";
  os << "Total unique methods accessed per class: "
     << Percent(total_unique_method_ids_, total_size) << "\n";
  os << "Total unique strings accessed per class: "
     << Percent(total_unique_string_ids_, total_size) << "\n";
  os << "Total unique types accessed per class: "
     << Percent(total_unique_types_, total_size) << "\n";
  const size_t same_class_total =
      same_class_direct_ +
      same_class_virtual_ +
      same_class_static_ +
      same_class_interface_ +
      same_class_super_;
  const size_t other_class_total =
      total_direct_ +
      total_virtual_ +
      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";
  os << "Type uses 1b savings: " << PercentDivide(uses_top_types_, total_size) << "\n";
  os << "Total Dex code bytes: " << Percent(dex_code_bytes_, total_size) << "\n";
  os << "Total unique code items: " << total_unique_code_items_ << "\n";
  os << "Total Dex size: " << total_size << "\n";
}

void CodeMetrics::ProcessDexFile(const DexFile& dex_file) {
  for (ClassAccessor accessor : dex_file.GetClasses()) {
    for (const ClassAccessor::Method& method : accessor.GetMethods()) {
      bool space_for_out_arg = false;
      for (const DexInstructionPcPair& inst : method.GetInstructions()) {
        switch (inst->Opcode()) {
          case Instruction::INVOKE_VIRTUAL:
          case Instruction::INVOKE_DIRECT:
          case Instruction::INVOKE_SUPER:
          case Instruction::INVOKE_INTERFACE:
          case Instruction::INVOKE_STATIC: {
            const uint32_t args = NumberOfArgs(inst.Inst());
            CHECK_LT(args, kMaxArgCount);
            ++arg_counts_[args];
            space_for_out_arg = args < kMaxArgCount - 1;
            break;
          }
          case Instruction::MOVE_RESULT:
          case Instruction::MOVE_RESULT_OBJECT: {
            if (space_for_out_arg && inst->VRegA_11x() < 16) {
              move_result_savings_ += inst->SizeInCodeUnits() * 2;
            }
            break;
          }
          default:
            space_for_out_arg = false;
            break;
        }
      }
    }
  }
}

void CodeMetrics::Dump(std::ostream& os, uint64_t total_size) const {
  const uint64_t total = std::accumulate(arg_counts_, arg_counts_ + kMaxArgCount, 0u);
  for (size_t i = 0; i < kMaxArgCount; ++i) {
    os << "args=" << i << ": " << Percent(arg_counts_[i], total) << "\n";
  }
  os << "Move result savings: " << Percent(move_result_savings_, total_size) << "\n";
  os << "One byte invoke savings: " << Percent(total, total_size) << "\n";
  const uint64_t low_arg_total = std::accumulate(arg_counts_, arg_counts_ + 2, 0u);
  os << "Low arg savings: " << Percent(low_arg_total * 2, total_size) << "\n";
}

}  // namespace dexanalyze
}  // namespace art
