partition_alloc.h 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. // Copyright (c) 2013 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_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_H_
  5. #define BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_H_
  6. #include "base/allocator/partition_allocator/partition_alloc_base/compiler_specific.h"
  7. #include "base/allocator/partition_allocator/partition_alloc_base/component_export.h"
  8. #include "base/allocator/partition_allocator/partition_alloc_forward.h"
  9. #include "base/allocator/partition_allocator/partition_oom.h"
  10. #include "base/allocator/partition_allocator/partition_root.h"
  11. // *** HOUSEKEEPING RULES ***
  12. //
  13. // Throughout PartitionAlloc code, we avoid using generic variable names like
  14. // |ptr| or |address|, and prefer names like |object|, |slot_start|, instead.
  15. // This helps emphasize that terms like "object" and "slot" represent two
  16. // different worlds. "Slot" is an indivisible allocation unit, internal to
  17. // PartitionAlloc. It is generally represented as an address (uintptr_t), since
  18. // arithmetic operations on it aren't uncommon, and for that reason it isn't
  19. // MTE-tagged either. "Object" is the allocated memory that the app is given via
  20. // interfaces like Alloc(), Free(), etc. An object is fully contained within a
  21. // slot, and may be surrounded by internal PartitionAlloc structures or empty
  22. // space. Is is generally represented as a pointer to its beginning (most
  23. // commonly void*), and is MTE-tagged so it's safe to access.
  24. //
  25. // The best way to transition between these to worlds is via
  26. // PartitionRoot::ObjectToSlotStart() and ::SlotStartToObject(). These take care
  27. // of shifting between slot/object start, MTE-tagging/untagging and the cast for
  28. // you. There are cases where these functions are insufficient. Internal
  29. // PartitionAlloc structures, like free-list pointers, BRP ref-count, cookie,
  30. // etc. are located in-slot thus accessing them requires an MTE tag.
  31. // SlotStartPtr2Addr() and SlotStartAddr2Ptr() take care of this.
  32. // There are cases where we have to do pointer arithmetic on an object pointer
  33. // (like check belonging to a pool, etc.), in which case we want to strip MTE
  34. // tag. ObjectInnerPtr2Addr() and ObjectPtr2Addr() take care of that.
  35. //
  36. // Avoid using UntagPtr/Addr() and TagPtr/Addr() directly, if possible. And
  37. // definitely avoid using reinterpret_cast between uintptr_t and pointer worlds.
  38. // When you do, add a comment explaining why it's safe from the point of MTE
  39. // tagging.
  40. namespace partition_alloc {
  41. PA_COMPONENT_EXPORT(PARTITION_ALLOC)
  42. void PartitionAllocGlobalInit(OomFunction on_out_of_memory);
  43. PA_COMPONENT_EXPORT(PARTITION_ALLOC)
  44. void PartitionAllocGlobalUninitForTesting();
  45. namespace internal {
  46. template <bool thread_safe>
  47. struct PA_COMPONENT_EXPORT(PARTITION_ALLOC) PartitionAllocator {
  48. PartitionAllocator() = default;
  49. ~PartitionAllocator();
  50. void init(PartitionOptions);
  51. PA_ALWAYS_INLINE PartitionRoot<thread_safe>* root() {
  52. return &partition_root_;
  53. }
  54. PA_ALWAYS_INLINE const PartitionRoot<thread_safe>* root() const {
  55. return &partition_root_;
  56. }
  57. private:
  58. PartitionRoot<thread_safe> partition_root_;
  59. };
  60. } // namespace internal
  61. using PartitionAllocator = internal::PartitionAllocator<internal::ThreadSafe>;
  62. } // namespace partition_alloc
  63. #endif // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_H_