service/init-classes/InitClassesWithSideEffects.h (30 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 <memory> #include <vector> #include "ConcurrentContainers.h" #include "DexClass.h" #include "IRInstruction.h" #include "MethodOverrideGraph.h" #include "MethodUtil.h" namespace init_classes { using InitClasses = std::vector<const DexClass*>; /** * For a given scope, this class provides information about which static * initializer with side effects get triggered when some class is initialized. */ class InitClassesWithSideEffects { private: ConcurrentMap<const DexType*, std::shared_ptr<InitClasses>> m_init_classes; std::atomic<size_t> m_trivial_init_classes{0}; InitClasses m_empty_init_classes; bool m_create_init_class_insns; const InitClasses* compute( const DexClass* cls, const method::ClInitHasNoSideEffectsPredicate& clinit_has_no_side_effects, const std::unordered_set<DexMethod*>* non_true_virtuals); public: InitClassesWithSideEffects( const Scope& scope, bool create_init_class_insns, const method_override_graph::Graph* method_override_graph = nullptr); // Determine list of classes with static initializers with side effects that // would get triggered when the given type is initialized. The list is ordered // such that base types come later. const InitClasses* get(const DexType* type) const; // Given a type to be initialized, determine the most derived class with a // static initializer with side effects that would get triggered, if any. const DexType* refine(const DexType* type) const; // Given a type to be initialized, create an init-class instruction with the // most derived class static initializer with side effects that would get // triggered. If there is no such class, returns nullptr. IRInstruction* create_init_class_insn(const DexType* type) const; }; } // namespace init_classes