Example #1
0
void TypeErasurePass::run_pass(DexStoresVector& stores,
                               ConfigFiles& conf,
                               PassManager& mgr) {
  // Type mapping file
  ModelMerger::s_mapping_file = conf.metafile(m_merged_type_mapping_file);
  Model::s_outdir = conf.get_outdir();

  // Setup Interdex plugin if any models.
  if (m_dex_sharding_model_specs.size() > 0) {
    interdex::InterDexRegistry* registry =
        static_cast<interdex::InterDexRegistry*>(
            PluginRegistry::get().pass_registry(interdex::INTERDEX_PASS_NAME));
    std::function<interdex::InterDexPassPlugin*()> fn =
        [&]() -> interdex::InterDexPassPlugin* {
      return new TypeErasureInterDexPlugin(m_dex_sharding_model_specs, mgr);
    };
    registry->register_plugin("TYPE_ERASURE_PLUGIN", std::move(fn));
  }

  if (m_model_specs.empty()) {
    return;
  }
  auto scope = build_class_scope(stores);
  Model::build_interdex_groups(&conf);
  for (ModelSpec& model_spec : m_model_specs) {
    if (!model_spec.enabled) {
      continue;
    }
    handle_interface_as_root(model_spec, scope, stores);
    erase_model(model_spec, scope, mgr, stores, conf);
  }
  post_dexen_changes(scope, stores);
}
Example #2
0
void SingleImplPass::run_pass(DexClassesVector& dexen, ConfigFiles& cfg, PassManager& mgr) {
  auto scope = build_class_scope(dexen);
  int max_steps = 0;
  while (true) {
    DEBUG_ONLY size_t scope_size = scope.size();
    TypeToTypes intfs_to_classes;
    TypeSet intfs;
    build_type_maps(scope, intfs_to_classes, intfs);
    TypeMap single_impl;
    collect_single_impl(intfs_to_classes, single_impl);

    std::unique_ptr<SingleImplAnalysis> single_impls =
        SingleImplAnalysis::analyze(
            scope, dexen[0], single_impl, intfs, m_pass_config);
    auto optimized = optimize(std::move(single_impls), scope);
    if (optimized == 0 || ++max_steps >= MAX_PASSES) break;
    removed_count += optimized;
    assert(scope_size > scope.size());
  }

  TRACE(INTF, 1, "Removed interfaces %ld\n", removed_count);
  TRACE(INTF, 1,
          "Updated invoke-interface to invoke-virtual %ld\n",
          s_invoke_intf_count);
  post_dexen_changes(scope, dexen);
}
Example #3
0
void SingleImplPass::run_pass(DexStoresVector& stores, ConfigFiles& cfg, PassManager& mgr) {
  auto scope = build_class_scope(stores);
  ClassHierarchy ch = build_type_hierarchy(scope);
  int max_steps = 0;
  size_t previous_invoke_intf_count = s_invoke_intf_count;
  removed_count = 0;
  while (true) {
    DEBUG_ONLY size_t scope_size = scope.size();
    TypeToTypes intfs_to_classes;
    TypeSet intfs;
    build_type_maps(scope, intfs_to_classes, intfs);
    TypeMap single_impl;
    collect_single_impl(intfs_to_classes, single_impl);

    std::unique_ptr<SingleImplAnalysis> single_impls =
        SingleImplAnalysis::analyze(
            scope, stores, single_impl, intfs, m_pass_config);
    auto optimized = optimize(
        std::move(single_impls), ch, scope, m_pass_config);
    if (optimized == 0 || ++max_steps >= MAX_PASSES) break;
    removed_count += optimized;
    assert(scope_size > scope.size());
  }

  TRACE(INTF, 1, "Removed interfaces %ld\n", removed_count);
  TRACE(INTF, 1,
          "Updated invoke-interface to invoke-virtual %ld\n",
          s_invoke_intf_count - previous_invoke_intf_count);

  mgr.incr_metric(METRIC_REMOVED_INTERFACES, removed_count);
  mgr.incr_metric(METRIC_INVOKE_INT_TO_VIRT,
                  s_invoke_intf_count - previous_invoke_intf_count);

  post_dexen_changes(scope, stores);
}
Example #4
0
void DelInitPass::run_pass(DexStoresVector& stores, ConfigFiles& cfg, PassManager& mgr) {
  if (!cfg.using_seeds && m_package_filter.size() == 0) {
    TRACE(DELINIT, 1, "No seeds information so not running DelInit\n");
    return;
  }
  package_filter = m_package_filter;
  auto scope = build_class_scope(stores);
  find_referenced_classes(scope);
  DeadRefs drefs;
  drefs.delinit(scope);
  TRACE(DELINIT, 1, "Removed %d <init> methods\n",
      drefs.del_init_res.deleted_inits);
  TRACE(DELINIT, 1, "Removed %d vmethods\n",
      drefs.del_init_res.deleted_vmeths);
  TRACE(DELINIT, 1, "Removed %d ifields\n",
      drefs.del_init_res.deleted_ifields);
  TRACE(DELINIT, 1, "Removed %d dmethods\n",
      drefs.del_init_res.deleted_dmeths);
  post_dexen_changes(scope, stores);
}
Example #5
0
void post_dexen_changes(const Scope& v, DexStoresVector& stores) {
  DexStoreClassesIterator iter(stores);
  post_dexen_changes(v, iter);
}
Example #6
0
void AnnoClassKillPass::run_pass(DexClassesVector& dexen, ConfigFiles& cfg) {
  auto scope = build_class_scope(dexen);
  auto kill_annos = get_kill_annos(m_kill_annos);
  kill_annotation_classes(scope, kill_annos);
  post_dexen_changes(scope, dexen);
}