]> git.saurik.com Git - apple/javascriptcore.git/blob - wtf/FastMalloc.h
61ebe327e433758555a1c331fbf8f726a9cc3d67
[apple/javascriptcore.git] / wtf / FastMalloc.h
1 /*
2 * Copyright (C) 2005, 2006, 2007, 2008 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 "Platform.h"
25 #include <stdlib.h>
26 #include <new>
27
28 namespace WTF {
29
30 // These functions call CRASH() if an allocation fails.
31 void* fastMalloc(size_t n);
32 void* fastZeroedMalloc(size_t n);
33 void* fastCalloc(size_t n_elements, size_t element_size);
34 void* fastRealloc(void* p, size_t n);
35
36 // These functions return NULL if an allocation fails.
37 void* tryFastMalloc(size_t n);
38 void* tryFastZeroedMalloc(size_t n);
39 void* tryFastCalloc(size_t n_elements, size_t element_size);
40 void* tryFastRealloc(void* p, size_t n);
41
42 void fastFree(void* p);
43
44 #ifndef NDEBUG
45 void fastMallocForbid();
46 void fastMallocAllow();
47 #endif
48
49 void releaseFastMallocFreeMemory();
50
51 struct FastMallocStatistics {
52 size_t heapSize;
53 size_t freeSizeInHeap;
54 size_t freeSizeInCaches;
55 size_t returnedSize;
56 };
57 FastMallocStatistics fastMallocStatistics();
58
59 // This defines a type which holds an unsigned integer and is the same
60 // size as the minimally aligned memory allocation.
61 typedef unsigned long long AllocAlignmentInteger;
62
63 namespace Internal {
64 enum AllocType { // Start with an unusual number instead of zero, because zero is common.
65 AllocTypeMalloc = 0x375d6750, // Encompasses fastMalloc, fastZeroedMalloc, fastCalloc, fastRealloc.
66 AllocTypeClassNew, // Encompasses class operator new from FastAllocBase.
67 AllocTypeClassNewArray, // Encompasses class operator new[] from FastAllocBase.
68 AllocTypeFastNew, // Encompasses fastNew.
69 AllocTypeFastNewArray, // Encompasses fastNewArray.
70 AllocTypeNew, // Encompasses global operator new.
71 AllocTypeNewArray // Encompasses global operator new[].
72 };
73 }
74
75 #if ENABLE(FAST_MALLOC_MATCH_VALIDATION)
76
77 // Malloc validation is a scheme whereby a tag is attached to an
78 // allocation which identifies how it was originally allocated.
79 // This allows us to verify that the freeing operation matches the
80 // allocation operation. If memory is allocated with operator new[]
81 // but freed with free or delete, this system would detect that.
82 // In the implementation here, the tag is an integer prepended to
83 // the allocation memory which is assigned one of the AllocType
84 // enumeration values. An alternative implementation of this
85 // scheme could store the tag somewhere else or ignore it.
86 // Users of FastMalloc don't need to know or care how this tagging
87 // is implemented.
88
89 namespace Internal {
90
91 // Return the AllocType tag associated with the allocated block p.
92 inline AllocType fastMallocMatchValidationType(const void* p)
93 {
94 const AllocAlignmentInteger* type = static_cast<const AllocAlignmentInteger*>(p) - 1;
95 return static_cast<AllocType>(*type);
96 }
97
98 // Return the address of the AllocType tag associated with the allocated block p.
99 inline AllocAlignmentInteger* fastMallocMatchValidationValue(void* p)
100 {
101 return reinterpret_cast<AllocAlignmentInteger*>(static_cast<char*>(p) - sizeof(AllocAlignmentInteger));
102 }
103
104 // Set the AllocType tag to be associaged with the allocated block p.
105 inline void setFastMallocMatchValidationType(void* p, AllocType allocType)
106 {
107 AllocAlignmentInteger* type = static_cast<AllocAlignmentInteger*>(p) - 1;
108 *type = static_cast<AllocAlignmentInteger>(allocType);
109 }
110
111 // Handle a detected alloc/free mismatch. By default this calls CRASH().
112 void fastMallocMatchFailed(void* p);
113
114 } // namespace Internal
115
116 // This is a higher level function which is used by FastMalloc-using code.
117 inline void fastMallocMatchValidateMalloc(void* p, Internal::AllocType allocType)
118 {
119 if (!p)
120 return;
121
122 Internal::setFastMallocMatchValidationType(p, allocType);
123 }
124
125 // This is a higher level function which is used by FastMalloc-using code.
126 inline void fastMallocMatchValidateFree(void* p, Internal::AllocType allocType)
127 {
128 if (!p)
129 return;
130
131 if (Internal::fastMallocMatchValidationType(p) != allocType)
132 Internal::fastMallocMatchFailed(p);
133 Internal::setFastMallocMatchValidationType(p, Internal::AllocTypeMalloc); // Set it to this so that fastFree thinks it's OK.
134 }
135
136 #else
137
138 inline void fastMallocMatchValidateMalloc(void*, Internal::AllocType)
139 {
140 }
141
142 inline void fastMallocMatchValidateFree(void*, Internal::AllocType)
143 {
144 }
145
146 #endif
147
148 } // namespace WTF
149
150 using WTF::fastMalloc;
151 using WTF::fastZeroedMalloc;
152 using WTF::fastCalloc;
153 using WTF::fastRealloc;
154 using WTF::tryFastMalloc;
155 using WTF::tryFastZeroedMalloc;
156 using WTF::tryFastCalloc;
157 using WTF::tryFastRealloc;
158 using WTF::fastFree;
159
160 #ifndef NDEBUG
161 using WTF::fastMallocForbid;
162 using WTF::fastMallocAllow;
163 #endif
164
165 #if COMPILER(GCC) && PLATFORM(DARWIN)
166 #define WTF_PRIVATE_INLINE __private_extern__ inline __attribute__((always_inline))
167 #elif COMPILER(GCC)
168 #define WTF_PRIVATE_INLINE inline __attribute__((always_inline))
169 #elif COMPILER(MSVC)
170 #define WTF_PRIVATE_INLINE __forceinline
171 #else
172 #define WTF_PRIVATE_INLINE inline
173 #endif
174
175 #ifndef _CRTDBG_MAP_ALLOC
176
177 #if !defined(USE_SYSTEM_MALLOC) || !(USE_SYSTEM_MALLOC)
178 WTF_PRIVATE_INLINE void* operator new(size_t s) { return fastMalloc(s); }
179 WTF_PRIVATE_INLINE void operator delete(void* p) { fastFree(p); }
180 WTF_PRIVATE_INLINE void* operator new[](size_t s) { return fastMalloc(s); }
181 WTF_PRIVATE_INLINE void operator delete[](void* p) { fastFree(p); }
182
183 #if PLATFORM(WINCE)
184 WTF_PRIVATE_INLINE void* operator new(size_t s, const std::nothrow_t&) throw() { return fastMalloc(s); }
185 WTF_PRIVATE_INLINE void operator delete(void* p, const std::nothrow_t&) throw() { fastFree(p); }
186 WTF_PRIVATE_INLINE void* operator new[](size_t s, const std::nothrow_t&) throw() { return fastMalloc(s); }
187 WTF_PRIVATE_INLINE void operator delete[](void* p, const std::nothrow_t&) throw() { fastFree(p); }
188 #endif
189 #endif
190
191 #endif // _CRTDBG_MAP_ALLOC
192
193 #endif /* WTF_FastMalloc_h */