void RemoveInterfacePass::remove_interfaces_for_root( const Scope& scope, const DexStoresVector& stores, const DexType* root, const TypeSystem& type_system) { TRACE(RM_INTF, 5, "Processing root %s\n", SHOW(root)); TypeSet interfaces; type_system.get_all_interface_children(root, interfaces); include_parent_interfaces(root, interfaces); m_total_num_interface += interfaces.size(); m_num_interface_excluded += exclude_unremovables( scope, stores, type_system, m_skip_multiple_targets_roots, m_include_primary_dex, interfaces); TRACE(RM_INTF, 5, "removable interfaces %ld\n", interfaces.size()); TypeSet removed = remove_leaf_interfaces(scope, root, interfaces, type_system); while (removed.size() > 0) { for (const auto intf : removed) { interfaces.erase(intf); m_removed_interfaces.insert(intf); } TRACE(RM_INTF, 5, "non-leaf removable interfaces %ld\n", interfaces.size()); removed = remove_leaf_interfaces(scope, root, interfaces, type_system); } // Update type reference to removed interfaces all at once. remove_interface_references(scope, type_system, root, m_removed_interfaces); if (traceEnabled(RM_INTF, 9)) { TypeSystem updated_ts(scope); for (const auto intf : interfaces) { TRACE(RM_INTF, 9, "unremoved interface %s\n", SHOW(intf)); TypeSet children; updated_ts.get_all_interface_children(intf, children); for (const auto cintf : children) { TRACE(RM_INTF, 9, " child %s\n", SHOW(cintf)); } } } }
/** * Run an optimization step. */ size_t OptimizationImpl::optimize(Scope& scope) { TypeList to_optimize; single_impls->get_interfaces(to_optimize); for (auto intf : to_optimize) { auto& intf_data = single_impls->get_single_impl_data(intf); TRACE(INTF, 3, "(OPT) %s => %s\n", SHOW(intf), SHOW(intf_data.cls)); if (intf_data.is_escaped()) continue; auto escape = can_optimize(intf, intf_data); if (escape != EscapeReason::NO_ESCAPE) { single_impls->escape_interface(intf, escape); continue; } do_optimize(intf, intf_data); optimized.insert(intf); } // make a new scope deleting all single impl interfaces Scope new_scope; for (auto cls : scope) { if (optimized.find(cls->get_type()) != optimized.end()) continue; new_scope.push_back(cls); } scope.swap(new_scope); return optimized.size(); }