1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_ALLOCATOR_PARTITION_ALLOCATOR_H_
6 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_ALLOCATOR_PARTITION_ALLOCATOR_H_
7 
8 // This is the allocator that is used for allocations that are not on the
9 // traced, garbage collected heap. It uses FastMalloc for collections,
10 // but uses the partition allocator for the backing store of the collections.
11 
12 #include <string.h>
13 #include "base/allocator/partition_allocator/partition_alloc_constants.h"
14 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
15 #include "third_party/blink/renderer/platform/wtf/assertions.h"
16 #include "third_party/blink/renderer/platform/wtf/type_traits.h"
17 #include "third_party/blink/renderer/platform/wtf/wtf_export.h"
18 
19 namespace WTF {
20 
21 class WTF_EXPORT PartitionAllocator {
22  public:
23   static constexpr bool kIsGarbageCollected = false;
24 
25   template <typename T>
MaxElementCountInBackingStore()26   static size_t MaxElementCountInBackingStore() {
27     return base::kGenericMaxDirectMapped / sizeof(T);
28   }
29 
30   template <typename T>
QuantizedSize(size_t count)31   static size_t QuantizedSize(size_t count) {
32     CHECK_LE(count, MaxElementCountInBackingStore<T>());
33     return WTF::Partitions::BufferActualSize(count * sizeof(T));
34   }
35   template <typename T>
AllocateVectorBacking(size_t size)36   static T* AllocateVectorBacking(size_t size) {
37     return reinterpret_cast<T*>(
38         AllocateBacking(size, WTF_HEAP_PROFILER_TYPE_NAME(T)));
39   }
40   static void FreeVectorBacking(void* address);
ExpandVectorBacking(void *,size_t)41   static inline bool ExpandVectorBacking(void*, size_t) { return false; }
ShrinkVectorBacking(void * address,size_t quantized_current_size,size_t quantized_shrunk_size)42   static inline bool ShrinkVectorBacking(void* address,
43                                          size_t quantized_current_size,
44                                          size_t quantized_shrunk_size) {
45     // Optimization: if we're downsizing inside the same allocator bucket,
46     // we can skip reallocation.
47     return quantized_current_size == quantized_shrunk_size;
48   }
49 
50   template <typename T, typename HashTable>
AllocateHashTableBacking(size_t size)51   static T* AllocateHashTableBacking(size_t size) {
52     return reinterpret_cast<T*>(
53         AllocateBacking(size, WTF_HEAP_PROFILER_TYPE_NAME(T)));
54   }
55   template <typename T, typename HashTable>
AllocateZeroedHashTableBacking(size_t size)56   static T* AllocateZeroedHashTableBacking(size_t size) {
57     void* result = AllocateBacking(size, WTF_HEAP_PROFILER_TYPE_NAME(T));
58     memset(result, 0, size);
59     return reinterpret_cast<T*>(result);
60   }
61   static void FreeHashTableBacking(void* address);
62 
63   template <typename Return, typename Metadata>
Malloc(size_t size,const char * type_name)64   static Return Malloc(size_t size, const char* type_name) {
65     return reinterpret_cast<Return>(
66         WTF::Partitions::FastMalloc(size, type_name));
67   }
68 
ExpandHashTableBacking(void *,size_t)69   static inline bool ExpandHashTableBacking(void*, size_t) { return false; }
Free(void * address)70   static void Free(void* address) { WTF::Partitions::FastFree(address); }
71   template <typename T>
NewArray(size_t bytes)72   static void* NewArray(size_t bytes) {
73     return Malloc<void*, void>(bytes, WTF_HEAP_PROFILER_TYPE_NAME(T));
74   }
DeleteArray(void * ptr)75   static void DeleteArray(void* ptr) {
76     Free(ptr);  // Not the system free, the one from this class.
77   }
78 
TraceBackingStoreIfMarked(const void *)79   static void TraceBackingStoreIfMarked(const void*) {}
80   template <typename T>
BackingWriteBarrier(T **)81   static void BackingWriteBarrier(T**) {}
82   template <typename, typename T>
BackingWriteBarrierForHashTable(T **)83   static void BackingWriteBarrierForHashTable(T**) {}
84 
IsAllocationAllowed()85   static bool IsAllocationAllowed() { return true; }
IsObjectResurrectionForbidden()86   static bool IsObjectResurrectionForbidden() { return false; }
IsSweepForbidden()87   static bool IsSweepForbidden() { return false; }
IsIncrementalMarking()88   static bool IsIncrementalMarking() { return false; }
89 
EnterGCForbiddenScope()90   static void EnterGCForbiddenScope() {}
LeaveGCForbiddenScope()91   static void LeaveGCForbiddenScope() {}
92 
93   template <typename T, typename Traits>
NotifyNewObject(T * object)94   static void NotifyNewObject(T* object) {}
95 
96   template <typename T, typename Traits>
NotifyNewObjects(T * array,size_t len)97   static void NotifyNewObjects(T* array, size_t len) {}
98 
99  private:
100   static void* AllocateBacking(size_t, const char* type_name);
101 };
102 
103 // Specializations for heap profiling, so type profiling of |char| is possible
104 // even in official builds (because |char| makes up a large portion of the
105 // heap.)
106 template <>
107 WTF_EXPORT char* PartitionAllocator::AllocateVectorBacking<char>(size_t);
108 
109 }  // namespace WTF
110 
111 #define USE_ALLOCATOR(ClassName, Allocator)                       \
112  public:                                                          \
113   void* operator new(size_t size) {                               \
114     return Allocator::template Malloc<void*, ClassName>(          \
115         size, WTF_HEAP_PROFILER_TYPE_NAME(ClassName));            \
116   }                                                               \
117   void operator delete(void* p) { Allocator::Free(p); }           \
118   void* operator new[](size_t size) {                             \
119     return Allocator::template NewArray<ClassName>(size);         \
120   }                                                               \
121   void operator delete[](void* p) { Allocator::DeleteArray(p); }  \
122   void* operator new(size_t, NotNullTag, void* location) {        \
123     DCHECK(location);                                             \
124     return location;                                              \
125   }                                                               \
126   void* operator new(size_t, void* location) { return location; } \
127                                                                   \
128  private:                                                         \
129   typedef int __thisIsHereToForceASemicolonAfterThisMacro
130 
131 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_ALLOCATOR_PARTITION_ALLOCATOR_H_
132