| // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_ALLOCATOR_PARTITION_ALLOCATOR_H_ |
| #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_ALLOCATOR_PARTITION_ALLOCATOR_H_ |
| |
| // This is the allocator that is used for allocations that are not on the |
| // traced, garbage collected heap. It uses FastMalloc for collections, |
| // but uses the partition allocator for the backing store of the collections. |
| |
| #include <string.h> |
| #include "base/allocator/partition_allocator/partition_alloc.h" |
| #include "third_party/blink/renderer/platform/wtf/allocator.h" |
| #include "third_party/blink/renderer/platform/wtf/assertions.h" |
| #include "third_party/blink/renderer/platform/wtf/type_traits.h" |
| #include "third_party/blink/renderer/platform/wtf/wtf_export.h" |
| |
| namespace WTF { |
| |
| class PartitionAllocatorDummyVisitor { |
| DISALLOW_NEW(); |
| }; |
| |
| class WTF_EXPORT PartitionAllocator { |
| public: |
| typedef PartitionAllocatorDummyVisitor Visitor; |
| static constexpr bool kIsGarbageCollected = false; |
| |
| template <typename T> |
| static size_t MaxElementCountInBackingStore() { |
| return base::kGenericMaxDirectMapped / sizeof(T); |
| } |
| |
| template <typename T> |
| static size_t QuantizedSize(size_t count) { |
| CHECK_LE(count, MaxElementCountInBackingStore<T>()); |
| return WTF::Partitions::BufferPartition()->ActualSize(count * sizeof(T)); |
| } |
| template <typename T> |
| static T* AllocateVectorBacking(size_t size) { |
| return reinterpret_cast<T*>( |
| AllocateBacking(size, WTF_HEAP_PROFILER_TYPE_NAME(T))); |
| } |
| template <typename T> |
| static T* AllocateExpandedVectorBacking(size_t size) { |
| return reinterpret_cast<T*>( |
| AllocateBacking(size, WTF_HEAP_PROFILER_TYPE_NAME(T))); |
| } |
| static void FreeVectorBacking(void* address); |
| static inline bool ExpandVectorBacking(void*, size_t) { return false; } |
| static inline bool ShrinkVectorBacking(void* address, |
| size_t quantized_current_size, |
| size_t quantized_shrunk_size) { |
| // Optimization: if we're downsizing inside the same allocator bucket, |
| // we can skip reallocation. |
| return quantized_current_size == quantized_shrunk_size; |
| } |
| template <typename T> |
| static T* AllocateInlineVectorBacking(size_t size) { |
| return AllocateVectorBacking<T>(size); |
| } |
| static inline void FreeInlineVectorBacking(void* address) { |
| FreeVectorBacking(address); |
| } |
| static inline bool ExpandInlineVectorBacking(void*, size_t) { return false; } |
| static inline bool ShrinkInlineVectorBacking(void* address, |
| size_t quantized_current_size, |
| size_t quantized_shrunk_size) { |
| return ShrinkVectorBacking(address, quantized_current_size, |
| quantized_shrunk_size); |
| } |
| |
| template <typename T, typename HashTable> |
| static T* AllocateHashTableBacking(size_t size) { |
| return reinterpret_cast<T*>( |
| AllocateBacking(size, WTF_HEAP_PROFILER_TYPE_NAME(T))); |
| } |
| template <typename T, typename HashTable> |
| static T* AllocateZeroedHashTableBacking(size_t size) { |
| void* result = AllocateBacking(size, WTF_HEAP_PROFILER_TYPE_NAME(T)); |
| memset(result, 0, size); |
| return reinterpret_cast<T*>(result); |
| } |
| static void FreeHashTableBacking(void* address); |
| |
| template <typename Return, typename Metadata> |
| static Return Malloc(size_t size, const char* type_name) { |
| return reinterpret_cast<Return>( |
| WTF::Partitions::FastMalloc(size, type_name)); |
| } |
| |
| static inline bool ExpandHashTableBacking(void*, size_t) { return false; } |
| static void Free(void* address) { WTF::Partitions::FastFree(address); } |
| template <typename T> |
| static void* NewArray(size_t bytes) { |
| return Malloc<void*, void>(bytes, WTF_HEAP_PROFILER_TYPE_NAME(T)); |
| } |
| static void DeleteArray(void* ptr) { |
| Free(ptr); // Not the system free, the one from this class. |
| } |
| |
| static void TraceMarkedBackingStore(void*) {} |
| static void BackingWriteBarrier(void*) {} |
| static void BackingWriteBarrier(void*, size_t) {} |
| |
| static bool IsAllocationAllowed() { return true; } |
| static bool IsObjectResurrectionForbidden() { return false; } |
| static bool IsSweepForbidden() { return false; } |
| |
| static void EnterGCForbiddenScope() {} |
| static void LeaveGCForbiddenScope() {} |
| |
| template <typename T, typename Traits> |
| static void NotifyNewObject(T* object) {} |
| |
| template <typename T, typename Traits> |
| static void NotifyNewObjects(T* array, size_t len) {} |
| |
| private: |
| static void* AllocateBacking(size_t, const char* type_name); |
| }; |
| |
| // Specializations for heap profiling, so type profiling of |char| is possible |
| // even in official builds (because |char| makes up a large portion of the |
| // heap.) |
| template <> |
| WTF_EXPORT char* PartitionAllocator::AllocateVectorBacking<char>(size_t); |
| template <> |
| WTF_EXPORT char* PartitionAllocator::AllocateExpandedVectorBacking<char>( |
| size_t); |
| |
| } // namespace WTF |
| |
| #define USE_ALLOCATOR(ClassName, Allocator) \ |
| public: \ |
| void* operator new(size_t size) { \ |
| return Allocator::template Malloc<void*, ClassName>( \ |
| size, WTF_HEAP_PROFILER_TYPE_NAME(ClassName)); \ |
| } \ |
| void operator delete(void* p) { Allocator::Free(p); } \ |
| void* operator new[](size_t size) { \ |
| return Allocator::template NewArray<ClassName>(size); \ |
| } \ |
| void operator delete[](void* p) { Allocator::DeleteArray(p); } \ |
| void* operator new(size_t, NotNullTag, void* location) { \ |
| DCHECK(location); \ |
| return location; \ |
| } \ |
| void* operator new(size_t, void* location) { return location; } \ |
| \ |
| private: \ |
| typedef int __thisIsHereToForceASemicolonAfterThisMacro |
| |
| #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_ALLOCATOR_PARTITION_ALLOCATOR_H_ |