xref: /aosp_15_r20/external/cronet/base/allocator/partition_allocator/src/partition_alloc/shim/allocator_shim.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2016 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 PARTITION_ALLOC_SHIM_ALLOCATOR_SHIM_H_
6 #define PARTITION_ALLOC_SHIM_ALLOCATOR_SHIM_H_
7 
8 #include <cstddef>
9 #include <cstdint>
10 
11 #include "partition_alloc/partition_alloc_buildflags.h"
12 
13 #if BUILDFLAG(USE_ALLOCATOR_SHIM)
14 #include "build/build_config.h"
15 #include "partition_alloc/partition_alloc_base/component_export.h"
16 #include "partition_alloc/partition_alloc_base/types/strong_alias.h"
17 #include "partition_alloc/shim/allocator_dispatch.h"
18 #include "partition_alloc/tagging.h"
19 
20 #if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) && BUILDFLAG(USE_STARSCAN)
21 #include "partition_alloc/starscan/pcscan.h"
22 #endif
23 
24 namespace allocator_shim {
25 
26 // Allocator Shim API. Allows to:
27 //  - Configure the behavior of the allocator (what to do on OOM failures).
28 //  - Install new hooks (AllocatorDispatch) in the allocator chain.
29 
30 // When this shim layer is enabled, the route of an allocation is as-follows:
31 //
32 // [allocator_shim_override_*.h] Intercept malloc() / operator new calls:
33 //   The override_* headers define the symbols required to intercept calls to
34 //   malloc() and operator new (if not overridden by specific C++ classes).
35 //
36 // [allocator_shim.cc] Routing allocation calls to the shim:
37 //   The headers above route the calls to the internal ShimMalloc(), ShimFree(),
38 //   ShimCppNew() etc. methods defined in allocator_shim.cc.
39 //   These methods will: (1) forward the allocation call to the front of the
40 //   AllocatorDispatch chain. (2) perform security hardenings (e.g., might
41 //   call std::new_handler on OOM failure).
42 //
43 // [allocator_shim_default_dispatch_to_*.cc] The AllocatorDispatch chain:
44 //   It is a singly linked list where each element is a struct with function
45 //   pointers (|malloc_function|, |free_function|, etc). Normally the chain
46 //   consists of a single AllocatorDispatch element, herein called
47 //   the "default dispatch", which is statically defined at build time and
48 //   ultimately routes the calls to the actual allocator defined by the build
49 //   config (glibc, ...).
50 //
51 // It is possible to dynamically insert further AllocatorDispatch stages
52 // to the front of the chain, for debugging / profiling purposes.
53 //
54 // All the functions must be thread safe. The shim does not enforce any
55 // serialization. This is to route to thread-aware allocators without
56 // introducing unnecessary perf hits.
57 
58 // When true makes malloc behave like new, w.r.t calling the new_handler if
59 // the allocation fails (see set_new_mode() in Windows).
60 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM)
61 void SetCallNewHandlerOnMallocFailure(bool value);
62 
63 // Allocates |size| bytes or returns nullptr. It does NOT call the new_handler,
64 // regardless of SetCallNewHandlerOnMallocFailure().
65 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM) void* UncheckedAlloc(size_t size);
66 
67 // Frees memory allocated with UncheckedAlloc().
68 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM) void UncheckedFree(void* ptr);
69 
70 // Inserts |dispatch| in front of the allocator chain. This method is
71 // thread-safe w.r.t concurrent invocations of InsertAllocatorDispatch().
72 // The callers have responsibility for inserting a single dispatch no more
73 // than once.
74 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM)
75 void InsertAllocatorDispatch(AllocatorDispatch* dispatch);
76 
77 // Test-only. Rationale: (1) lack of use cases; (2) dealing safely with a
78 // removal of arbitrary elements from a singly linked list would require a lock
79 // in malloc(), which we really don't want.
80 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM)
81 void RemoveAllocatorDispatchForTesting(AllocatorDispatch* dispatch);
82 
83 #if BUILDFLAG(IS_APPLE)
84 // The fallback function to be called when try_free_default_function receives a
85 // pointer which doesn't belong to the allocator.
86 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM)
87 void TryFreeDefaultFallbackToFindZoneAndFree(void* ptr);
88 #endif  // BUILDFLAG(IS_APPLE)
89 
90 #if BUILDFLAG(IS_APPLE)
91 #if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
92 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM)
93 void InitializeDefaultAllocatorPartitionRoot();
94 bool IsDefaultAllocatorPartitionRootInitialized();
95 #endif  // BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
96 // On macOS, the allocator shim needs to be turned on during runtime.
97 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM) void InitializeAllocatorShim();
98 #endif  // BUILDFLAG(IS_APPLE)
99 
100 #if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
101 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM) void EnablePartitionAllocMemoryReclaimer();
102 
103 using EnableBrp =
104     partition_alloc::internal::base::StrongAlias<class EnableBrpTag, bool>;
105 using EnableMemoryTagging =
106     partition_alloc::internal::base::StrongAlias<class EnableMemoryTaggingTag,
107                                                  bool>;
108 enum class BucketDistribution : uint8_t { kNeutral, kDenser };
109 using SchedulerLoopQuarantine = partition_alloc::internal::base::
110     StrongAlias<class SchedulerLoopQuarantineTag, bool>;
111 using ZappingByFreeFlags =
112     partition_alloc::internal::base::StrongAlias<class ZappingByFreeFlagsTag,
113                                                  bool>;
114 
115 using UsePoolOffsetFreelists = partition_alloc::internal::base::
116     StrongAlias<class UsePoolOffsetFreelistsTag, bool>;
117 
118 // If |thread_cache_on_non_quarantinable_partition| is specified, the
119 // thread-cache will be enabled on the non-quarantinable partition. The
120 // thread-cache on the main (malloc) partition will be disabled.
121 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM)
122 void ConfigurePartitions(
123     EnableBrp enable_brp,
124     EnableMemoryTagging enable_memory_tagging,
125     partition_alloc::TagViolationReportingMode memory_tagging_reporting_mode,
126     BucketDistribution distribution,
127     SchedulerLoopQuarantine scheduler_loop_quarantine,
128     size_t scheduler_loop_quarantine_capacity_in_bytes,
129     ZappingByFreeFlags zapping_by_free_flags,
130     UsePoolOffsetFreelists use_pool_offset_freelists);
131 
132 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM) uint32_t GetMainPartitionRootExtrasSize();
133 
134 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM) void AdjustDefaultAllocatorForForeground();
135 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM) void AdjustDefaultAllocatorForBackground();
136 
137 #if BUILDFLAG(USE_STARSCAN)
138 PA_COMPONENT_EXPORT(ALLOCATOR_SHIM)
139 void EnablePCScan(partition_alloc::internal::PCScan::InitConfig);
140 #endif
141 #endif  // BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
142 
143 }  // namespace allocator_shim
144 
145 #endif  // BUILDFLAG(USE_ALLOCATOR_SHIM)
146 
147 #endif  // PARTITION_ALLOC_SHIM_ALLOCATOR_SHIM_H_
148