1 // Copyright 2021 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_STARSCAN_METADATA_ALLOCATOR_H_ 6 #define BASE_ALLOCATOR_PARTITION_ALLOCATOR_STARSCAN_METADATA_ALLOCATOR_H_ 7 8 #include <utility> 9 10 #include "base/allocator/partition_allocator/partition_alloc_base/component_export.h" 11 #include "base/allocator/partition_allocator/partition_alloc_constants.h" 12 #include "base/allocator/partition_allocator/partition_root.h" 13 14 namespace partition_alloc::internal { 15 16 PA_COMPONENT_EXPORT(PARTITION_ALLOC) 17 ThreadSafePartitionRoot& PCScanMetadataAllocator(); 18 void ReinitPCScanMetadataAllocatorForTesting(); 19 20 // STL allocator which is needed to keep internal data structures required by 21 // PCScan. 22 template <typename T> 23 class MetadataAllocator { 24 public: 25 using value_type = T; 26 27 MetadataAllocator() = default; 28 29 template <typename U> MetadataAllocator(const MetadataAllocator<U> &)30 MetadataAllocator(const MetadataAllocator<U>&) {} // NOLINT 31 32 template <typename U> 33 MetadataAllocator& operator=(const MetadataAllocator<U>&) { 34 return *this; 35 } 36 37 template <typename U> 38 bool operator==(const MetadataAllocator<U>&) { 39 return true; 40 } 41 42 template <typename U> 43 bool operator!=(const MetadataAllocator<U>& o) { 44 return !operator==(o); 45 } 46 allocate(size_t size)47 value_type* allocate(size_t size) { 48 return static_cast<value_type*>( 49 PCScanMetadataAllocator().AllocWithFlagsNoHooks( 50 0, size * sizeof(value_type), PartitionPageSize())); 51 } 52 deallocate(value_type * ptr,size_t size)53 void deallocate(value_type* ptr, size_t size) { 54 PCScanMetadataAllocator().FreeNoHooks(ptr); 55 } 56 }; 57 58 // Inherit from it to make a class allocated on the metadata partition. 59 struct AllocatedOnPCScanMetadataPartition { newAllocatedOnPCScanMetadataPartition60 static void* operator new(size_t size) { 61 return PCScanMetadataAllocator().AllocWithFlagsNoHooks(0, size, 62 PartitionPageSize()); 63 } deleteAllocatedOnPCScanMetadataPartition64 static void operator delete(void* ptr) { 65 PCScanMetadataAllocator().FreeNoHooks(ptr); 66 } 67 }; 68 69 template <typename T, typename... Args> MakePCScanMetadata(Args &&...args)70T* MakePCScanMetadata(Args&&... args) { 71 auto* memory = 72 static_cast<T*>(PCScanMetadataAllocator().AllocWithFlagsNoHooks( 73 0, sizeof(T), PartitionPageSize())); 74 return new (memory) T(std::forward<Args>(args)...); 75 } 76 77 struct PCScanMetadataDeleter final { operatorfinal78 inline void operator()(void* ptr) const { 79 PCScanMetadataAllocator().FreeNoHooks(ptr); 80 } 81 }; 82 83 } // namespace partition_alloc::internal 84 85 #endif // BASE_ALLOCATOR_PARTITION_ALLOCATOR_STARSCAN_METADATA_ALLOCATOR_H_ 86