Unreviewed, rolling out r221552.
[WebKit-https.git] / Source / WTF / wtf / FastMalloc.h
1 /*
2  *  Copyright (C) 2005-2009, 2015-2016 Apple Inc. All rights reserved.
3  *
4  *  This library is free software; you can redistribute it and/or
5  *  modify it under the terms of the GNU Library General Public
6  *  License as published by the Free Software Foundation; either
7  *  version 2 of the License, or (at your option) any later version.
8  *
9  *  This library is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  *  Library General Public License for more details.
13  *
14  *  You should have received a copy of the GNU Library General Public License
15  *  along with this library; see the file COPYING.LIB.  If not, write to
16  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  *  Boston, MA 02110-1301, USA.
18  *
19  */
20
21 #ifndef WTF_FastMalloc_h
22 #define WTF_FastMalloc_h
23
24 #include <new>
25 #include <stdlib.h>
26 #include <wtf/StdLibExtras.h>
27
28 namespace WTF {
29
30 #if !defined(NDEBUG)
31 WTF_EXPORT_PRIVATE void fastSetMaxSingleAllocationSize(size_t);
32 #endif
33
34 class TryMallocReturnValue {
35 public:
36     TryMallocReturnValue(void*);
37     TryMallocReturnValue(TryMallocReturnValue&&);
38     ~TryMallocReturnValue();
39     template<typename T> bool getValue(T*&) WARN_UNUSED_RETURN;
40 private:
41     void operator=(TryMallocReturnValue&&) = delete;
42     mutable void* m_data;
43 };
44
45 WTF_EXPORT_PRIVATE bool isFastMallocEnabled();
46
47 // These functions call CRASH() if an allocation fails.
48 WTF_EXPORT_PRIVATE void* fastMalloc(size_t) RETURNS_NONNULL;
49 WTF_EXPORT_PRIVATE void* fastZeroedMalloc(size_t) RETURNS_NONNULL;
50 WTF_EXPORT_PRIVATE void* fastCalloc(size_t numElements, size_t elementSize) RETURNS_NONNULL;
51 WTF_EXPORT_PRIVATE void* fastRealloc(void*, size_t) RETURNS_NONNULL;
52 WTF_EXPORT_PRIVATE char* fastStrDup(const char*) RETURNS_NONNULL;
53
54 WTF_EXPORT_PRIVATE TryMallocReturnValue tryFastMalloc(size_t);
55 TryMallocReturnValue tryFastZeroedMalloc(size_t);
56 WTF_EXPORT_PRIVATE TryMallocReturnValue tryFastCalloc(size_t numElements, size_t elementSize);
57
58 WTF_EXPORT_PRIVATE void fastFree(void*);
59
60 // Allocations from fastAlignedMalloc() must be freed using fastAlignedFree().
61 WTF_EXPORT_PRIVATE void* fastAlignedMalloc(size_t alignment, size_t) RETURNS_NONNULL;
62 WTF_EXPORT_PRIVATE void* tryFastAlignedMalloc(size_t alignment, size_t);
63 WTF_EXPORT_PRIVATE void fastAlignedFree(void*);
64
65 WTF_EXPORT_PRIVATE size_t fastMallocSize(const void*);
66
67 // FIXME: This is non-helpful; fastMallocGoodSize will be removed soon.
68 WTF_EXPORT_PRIVATE size_t fastMallocGoodSize(size_t);
69
70 WTF_EXPORT_PRIVATE void releaseFastMallocFreeMemory();
71 WTF_EXPORT_PRIVATE void releaseFastMallocFreeMemoryForThisThread();
72
73 struct FastMallocStatistics {
74     size_t reservedVMBytes;
75     size_t committedVMBytes;
76     size_t freeListBytes;
77 };
78 WTF_EXPORT_PRIVATE FastMallocStatistics fastMallocStatistics();
79
80 // This defines a type which holds an unsigned integer and is the same
81 // size as the minimally aligned memory allocation.
82 typedef unsigned long long AllocAlignmentInteger;
83
84 inline TryMallocReturnValue::TryMallocReturnValue(void* data)
85     : m_data(data)
86 {
87 }
88
89 inline TryMallocReturnValue::TryMallocReturnValue(TryMallocReturnValue&& source)
90     : m_data(source.m_data)
91 {
92     source.m_data = nullptr;
93 }
94
95 inline TryMallocReturnValue::~TryMallocReturnValue()
96 {
97     ASSERT(!m_data);
98 }
99
100 template<typename T> inline bool TryMallocReturnValue::getValue(T*& data)
101 {
102     data = static_cast<T*>(m_data);
103     m_data = nullptr;
104     return data;
105 }
106
107 // C++ STL allocator implementation. You can integrate fastMalloc into STL containers.
108 // e.g. std::unordered_map<Key, Value, std::hash<Key>, std::equal_to<Key>, FastAllocator<std::pair<const Key, Value>>>.
109 template<typename T>
110 class FastAllocator {
111 public:
112     using value_type = T;
113
114     FastAllocator() = default;
115
116     template<typename U> FastAllocator(const FastAllocator<U>&) { }
117
118     T* allocate(size_t count)
119     {
120         return reinterpret_cast<T*>(fastMalloc(sizeof(T) * count));
121     }
122
123     void deallocate(T* pointer, size_t)
124     {
125         fastFree(pointer);
126     }
127 };
128
129 template<typename T, typename U> inline bool operator==(const FastAllocator<T>&, const FastAllocator<U>&) { return true; }
130 template<typename T, typename U> inline bool operator!=(const FastAllocator<T>&, const FastAllocator<U>&) { return false; }
131
132 struct FastMalloc {
133     static void* malloc(size_t size) { return fastMalloc(size); }
134     
135     static void* tryMalloc(size_t size)
136     {
137         auto result = tryFastMalloc(size);
138         void* realResult;
139         if (result.getValue(realResult))
140             return realResult;
141         return nullptr;
142     }
143     
144     static void* realloc(void* p, size_t size) { return fastRealloc(p, size); }
145     
146     static void free(void* p) { fastFree(p); }
147 };
148
149 } // namespace WTF
150
151 #if !defined(NDEBUG)
152 using WTF::fastSetMaxSingleAllocationSize;
153 #endif
154
155 using WTF::FastAllocator;
156 using WTF::FastMalloc;
157 using WTF::isFastMallocEnabled;
158 using WTF::fastCalloc;
159 using WTF::fastFree;
160 using WTF::fastMalloc;
161 using WTF::fastMallocGoodSize;
162 using WTF::fastMallocSize;
163 using WTF::fastRealloc;
164 using WTF::fastStrDup;
165 using WTF::fastZeroedMalloc;
166 using WTF::tryFastAlignedMalloc;
167 using WTF::tryFastCalloc;
168 using WTF::tryFastMalloc;
169 using WTF::tryFastZeroedMalloc;
170 using WTF::fastAlignedMalloc;
171 using WTF::fastAlignedFree;
172
173 #if COMPILER(GCC_OR_CLANG) && OS(DARWIN)
174 #define WTF_PRIVATE_INLINE __private_extern__ inline __attribute__((always_inline))
175 #elif COMPILER(GCC_OR_CLANG)
176 #define WTF_PRIVATE_INLINE inline __attribute__((always_inline))
177 #elif COMPILER(MSVC)
178 #define WTF_PRIVATE_INLINE __forceinline
179 #else
180 #define WTF_PRIVATE_INLINE inline
181 #endif
182
183 #define WTF_MAKE_FAST_ALLOCATED \
184 public: \
185     void* operator new(size_t, void* p) { return p; } \
186     void* operator new[](size_t, void* p) { return p; } \
187     \
188     void* operator new(size_t size) \
189     { \
190         return ::WTF::fastMalloc(size); \
191     } \
192     \
193     void operator delete(void* p) \
194     { \
195         ::WTF::fastFree(p); \
196     } \
197     \
198     void* operator new[](size_t size) \
199     { \
200         return ::WTF::fastMalloc(size); \
201     } \
202     \
203     void operator delete[](void* p) \
204     { \
205         ::WTF::fastFree(p); \
206     } \
207     void* operator new(size_t, NotNullTag, void* location) \
208     { \
209         ASSERT(location); \
210         return location; \
211     } \
212 private: \
213 typedef int __thisIsHereToForceASemicolonAfterThisMacro
214
215 #endif /* WTF_FastMalloc_h */