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)29InternalAllocator<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)38void 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)44T* 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)52void 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