opt/annokill/AnnoKill.h (110 lines of code) (raw):

/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include "Pass.h" #include <map> #include <string> #include <unordered_set> #include <vector> #include "ConcurrentContainers.h" class DexAnnotation; class DexAnnotationSet; class AnnoKill { public: using AnnoSet = std::unordered_set<DexType*>; using AnnoNames = std::vector<std::string>; struct AnnoKillStats { size_t annotations; size_t annotations_killed; size_t class_asets; size_t class_asets_cleared; size_t method_asets; size_t method_asets_cleared; size_t method_param_asets; size_t method_param_asets_cleared; size_t field_asets; size_t field_asets_cleared; size_t visibility_build_count; size_t visibility_runtime_count; size_t visibility_system_count; size_t signatures_killed; AnnoKillStats() { memset(this, 0, sizeof(AnnoKillStats)); } AnnoKillStats& operator+=(const AnnoKillStats& rhs) { annotations += rhs.annotations; annotations_killed += rhs.annotations_killed; class_asets += rhs.class_asets; class_asets_cleared += rhs.class_asets_cleared; method_asets += rhs.method_asets; method_asets_cleared += rhs.method_asets_cleared; method_param_asets += rhs.method_param_asets; method_param_asets_cleared += rhs.method_param_asets_cleared; field_asets += rhs.field_asets; field_asets_cleared += rhs.field_asets_cleared; visibility_build_count += rhs.visibility_build_count; visibility_runtime_count += rhs.visibility_runtime_count; visibility_system_count += rhs.visibility_system_count; signatures_killed += rhs.signatures_killed; return *this; } }; AnnoKill(Scope& scope, bool only_force_kill, bool kill_bad_signatures, const AnnoNames& keep, const AnnoNames& kill, const AnnoNames& force_kill, const std::unordered_map<std::string, std::vector<std::string>>& class_hierarchy_keep_annos, const std::unordered_map<std::string, std::vector<std::string>>& annotated_keep_annos); bool kill_annotations(); std::unordered_set<const DexType*> build_anno_keep( DexAnnotationSet* aset) const; bool should_kill_bad_signature(DexAnnotation* da) const; AnnoKillStats get_stats() const { return m_stats; } private: // Gets the set of all annotations referenced in code // either by the use of SomeClass.class, as a parameter of a method // call or if the annotation is a field of a class. AnnoSet get_referenced_annos(); // Retrieves the list of annotation instances that match the given set // of annotation types to be removed. AnnoSet get_removable_annotation_instances(); void cleanup_aset(DexAnnotationSet* aset, const AnnoSet& referenced_annos, AnnoKillStats& stats, const std::unordered_set<const DexType*>& keep_annos = std::unordered_set<const DexType*>{}) const; void count_annotation(const DexAnnotation* da, AnnoKillStats& stats) const; Scope& m_scope; const bool m_only_force_kill; const bool m_kill_bad_signatures; AnnoSet m_kill; AnnoSet m_force_kill; AnnoSet m_keep; AnnoKillStats m_stats; mutable ConcurrentMap<std::string, size_t> m_build_anno_map; mutable ConcurrentMap<std::string, size_t> m_runtime_anno_map; mutable ConcurrentMap<std::string, size_t> m_system_anno_map; std::unordered_map<const DexType*, std::unordered_set<const DexType*>> m_anno_class_hierarchy_keep; std::unordered_map<const DexType*, std::unordered_set<const DexType*>> m_annotated_keep_annos; }; class AnnoKillPass : public Pass { public: AnnoKillPass() : Pass("AnnoKillPass") {} explicit AnnoKillPass(const char* name) : Pass(name) {} void bind_config() override { bind("keep_annos", {}, m_keep_annos); bind("kill_annos", {}, m_kill_annos); bind("force_kill_annos", {}, m_force_kill_annos); bind("kill_bad_signatures", false, m_kill_bad_signatures); bind("class_hierarchy_keep_annos", {}, m_class_hierarchy_keep_annos); bind("annotated_keep_annos", {}, m_annotated_keep_annos); } void run_pass(DexStoresVector&, ConfigFiles&, PassManager&) override; virtual bool only_force_kill() const { return false; } private: std::vector<std::string> m_keep_annos; std::vector<std::string> m_kill_annos; std::vector<std::string> m_force_kill_annos; std::unordered_map<std::string, std::vector<std::string>> m_class_hierarchy_keep_annos; std::unordered_map<std::string, std::vector<std::string>> m_annotated_keep_annos; bool m_kill_bad_signatures; };