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