1 // Copyright 2024 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_INTERNAL_ALLOCATOR_H_
6 #define PARTITION_ALLOC_INTERNAL_ALLOCATOR_H_
7 
8 #include <new>
9 #include <type_traits>
10 
11 #include "partition_alloc/internal_allocator_forward.h"
12 #include "partition_alloc/partition_alloc_base/component_export.h"
13 #include "partition_alloc/partition_root.h"
14 
15 // Internal Allocator can be used to get heap allocations required to
16 // implement PartitionAlloc's feature.
17 // As Internal Allocator being PartitionAlloc with minimal configuration,
18 // it is not allowed to use this allocator for PA's core implementation to avoid
19 // reentrancy issues. Also don't use this when satisfying the very first PA-E
20 // allocation of the process.
21 
22 namespace partition_alloc::internal {
23 
24 PA_COMPONENT_EXPORT(PARTITION_ALLOC)
25 PartitionRoot& InternalAllocatorRoot();
26 
27 // A class that meets C++ named requirements, Allocator.
28 template <typename T>
allocate(std::size_t count)29 InternalAllocator<T>::value_type* InternalAllocator<T>::allocate(
30     std::size_t count) {
31   PA_CHECK(count <=
32            std::numeric_limits<std::size_t>::max() / sizeof(value_type));
33   return static_cast<value_type*>(
34       InternalAllocatorRoot().Alloc<AllocFlags::kNoHooks>(count *
35                                                           sizeof(value_type)));
36 }
37 template <typename T>
deallocate(value_type * ptr,std::size_t)38 void InternalAllocator<T>::deallocate(value_type* ptr, std::size_t) {
39   InternalAllocatorRoot().Free<FreeFlags::kNoHooks>(ptr);
40 }
41 
42 // Create an object on heap in the internal partition.
43 template <typename T, typename... Args>
ConstructAtInternalPartition(Args &&...args)44 T* ConstructAtInternalPartition(Args&&... args) {
45   auto* memory = static_cast<T*>(
46       InternalAllocatorRoot().Alloc<AllocFlags::kNoHooks>(sizeof(T)));
47   return new (memory) T(std::forward<Args>(args)...);
48 }
49 
50 // Destroy an object on heap in the internal partition.
51 template <typename T>
DestroyAtInternalPartition(T * ptr)52 void DestroyAtInternalPartition(T* ptr) {
53   // Destroying an array is not supported.
54   static_assert(!std::is_array_v<T>);
55   ptr->~T();
56   InternalAllocatorRoot().Free<FreeFlags::kNoHooks>(ptr);
57 }
58 
59 }  // namespace partition_alloc::internal
60 
61 #endif  // PARTITION_ALLOC_INTERNAL_ALLOCATOR_H_
62