• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (C) 2005, 2006, 2007, 2008, 2009 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);
32     void* fastZeroedMalloc(size_t);
33     void* fastCalloc(size_t numElements, size_t elementSize);
34     void* fastRealloc(void*, size_t);
35 
36     // These functions return 0 if an allocation fails.
37     void* tryFastMalloc(size_t);
38     void* tryFastZeroedMalloc(size_t);
39     void* tryFastCalloc(size_t numElements, size_t elementSize);
40     void* tryFastRealloc(void*, size_t);
41 
42     void fastFree(void*);
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.
fastMallocMatchValidationType(const void * 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.
fastMallocMatchValidationValue(void * 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.
setFastMallocMatchValidationType(void * p,AllocType allocType)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.
fastMallocMatchValidateMalloc(void * p,Internal::AllocType allocType)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.
fastMallocMatchValidateFree(void * p,Internal::AllocType allocType)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 
fastMallocMatchValidateMalloc(void *,Internal::AllocType)138     inline void fastMallocMatchValidateMalloc(void*, Internal::AllocType)
139     {
140     }
141 
fastMallocMatchValidateFree(void *,Internal::AllocType)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 #if !defined(_CRTDBG_MAP_ALLOC) && !(defined(USE_SYSTEM_MALLOC) && USE_SYSTEM_MALLOC)
176 
177 // The nothrow functions here are actually not all that helpful, because fastMalloc will
178 // call CRASH() rather than returning 0, and returning 0 is what nothrow is all about.
179 // But since WebKit code never uses exceptions or nothrow at all, this is probably OK.
180 // Long term we will adopt FastAllocBase.h everywhere, and and replace this with
181 // debug-only code to make sure we don't use the system malloc via the default operator
182 // new by accident.
183 
new(size_t size)184 WTF_PRIVATE_INLINE void* operator new(size_t size) { return fastMalloc(size); }
new(size_t size,const std::nothrow_t &)185 WTF_PRIVATE_INLINE void* operator new(size_t size, const std::nothrow_t&) throw() { return fastMalloc(size); }
delete(void * p)186 WTF_PRIVATE_INLINE void operator delete(void* p) { fastFree(p); }
delete(void * p,const std::nothrow_t &)187 WTF_PRIVATE_INLINE void operator delete(void* p, const std::nothrow_t&) throw() { fastFree(p); }
188 WTF_PRIVATE_INLINE void* operator new[](size_t size) { return fastMalloc(size); }
throw()189 WTF_PRIVATE_INLINE void* operator new[](size_t size, const std::nothrow_t&) throw() { return fastMalloc(size); }
190 WTF_PRIVATE_INLINE void operator delete[](void* p) { fastFree(p); }
throw()191 WTF_PRIVATE_INLINE void operator delete[](void* p, const std::nothrow_t&) throw() { fastFree(p); }
192 
193 #endif
194 
195 #endif /* WTF_FastMalloc_h */
196