reached_addresses_bitset.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef BASE_ANDROID_REACHED_ADDRESSES_BITSET_H_
  5. #define BASE_ANDROID_REACHED_ADDRESSES_BITSET_H_
  6. #include <atomic>
  7. #include <vector>
  8. #include "base/base_export.h"
  9. namespace base {
  10. template <typename T>
  11. class NoDestructor;
  12. namespace android {
  13. // ReachedAddressesBitset is a set that stores addresses for the
  14. // ReachedCodeProfiler in compact form. Its main features are lock-free
  15. // thread-safety and fast adding of elements.
  16. //
  17. // The addresses are kept with |kBytesGranularity| to save the storage space.
  18. //
  19. // Once insterted, elements cannot be erased from the set.
  20. //
  21. // All methods can be called from any thread.
  22. class BASE_EXPORT ReachedAddressesBitset {
  23. public:
  24. // Returns an instance of ReachedAddressesBitset having enough storage space
  25. // to keep all addresses from the .text section.
  26. // Returns nullptr if SUPPORTS_CODE_ORDERING isn't defined.
  27. // This instance is stored in the .bss section of the binary, meaning that it
  28. // doesn't incur the binary size overhead and it doesn't increase the resident
  29. // memory footprint when not used.
  30. static ReachedAddressesBitset* GetTextBitset();
  31. // Inserts |address| into the bitset iff |address| lies in the range between
  32. // |start_address_| and |end_address_|.
  33. void RecordAddress(uintptr_t address);
  34. // Returns a list of recorded addresses in the form of offsets from
  35. // |start_address_|.
  36. std::vector<uint32_t> GetReachedOffsets() const;
  37. private:
  38. friend class ReachedAddressesBitsetTest;
  39. friend class NoDestructor<ReachedAddressesBitset>;
  40. // Represents the number of bytes that are mapped into the same bit in the
  41. // bitset.
  42. static constexpr size_t kBytesGranularity = 4;
  43. // Constructs a ReachedAddressesBitset on top of an external storage of
  44. // |storage_size| pointed by |storage_ptr|. This external storage must outlive
  45. // the constructed bitset instance. The size of storage must be large enough
  46. // to fit all addresses in the range between |start_address| and
  47. // |end_address|.
  48. ReachedAddressesBitset(uintptr_t start_address,
  49. uintptr_t end_address,
  50. std::atomic<uint32_t>* storage_ptr,
  51. size_t storage_size);
  52. size_t NumberOfReachableElements() const;
  53. uintptr_t start_address_;
  54. uintptr_t end_address_;
  55. std::atomic<uint32_t>* reached_;
  56. };
  57. } // namespace android
  58. } // namespace base
  59. #endif // BASE_ANDROID_REACHED_ADDRESSES_BITSET_H_