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); }
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); }
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); }
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); }
void post_dexen_changes(const Scope& v, DexStoresVector& stores) { DexStoreClassesIterator iter(stores); post_dexen_changes(v, iter); }
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); }