| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. | 2 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
| 5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
| 6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
| 7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
| 8 * | 8 * |
| 9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 12 * Library General Public License for more details. | 12 * Library General Public License for more details. |
| 13 * | 13 * |
| 14 * You should have received a copy of the GNU Library General Public License | 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 | 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, | 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 17 * Boston, MA 02110-1301, USA. | 17 * Boston, MA 02110-1301, USA. |
| 18 * | 18 * |
| 19 */ | 19 */ |
| 20 | 20 |
| 21 #ifndef WTF_FastMalloc_h | 21 #ifndef WTF_FastMalloc_h |
| 22 #define WTF_FastMalloc_h | 22 #define WTF_FastMalloc_h |
| 23 | 23 |
| 24 #include <new> | |
| 25 #include <stdlib.h> | |
| 26 | |
| 27 #include "wtf/Platform.h" | |
| 28 #include "wtf/PossiblyNull.h" | |
| 29 #include "wtf/WTFExport.h" | 24 #include "wtf/WTFExport.h" |
| 25 #include <cstddef> |
| 30 | 26 |
| 31 namespace WTF { | 27 namespace WTF { |
| 32 | 28 |
| 33 // These functions call CRASH() if an allocation fails. | 29 // These functions crash safely if an allocation fails. |
| 34 WTF_EXPORT void* fastMalloc(size_t); | 30 WTF_EXPORT void* fastMalloc(size_t); |
| 35 WTF_EXPORT void* fastZeroedMalloc(size_t); | 31 WTF_EXPORT void* fastZeroedMalloc(size_t); |
| 36 WTF_EXPORT void* fastCalloc(size_t numElements, size_t elementSize); | 32 WTF_EXPORT void* fastCalloc(size_t numElements, size_t elementSize); |
| 37 WTF_EXPORT void* fastRealloc(void*, size_t); | 33 WTF_EXPORT void* fastRealloc(void*, size_t); |
| 38 WTF_EXPORT char* fastStrDup(const char*); | 34 WTF_EXPORT char* fastStrDup(const char*); |
| 39 WTF_EXPORT size_t fastMallocGoodSize(size_t); | 35 WTF_EXPORT size_t fastMallocGoodSize(size_t); |
| 40 | 36 |
| 41 struct TryMallocReturnValue { | |
| 42 TryMallocReturnValue(void* data) | |
| 43 : m_data(data) | |
| 44 { | |
| 45 } | |
| 46 TryMallocReturnValue(const TryMallocReturnValue& source) | |
| 47 : m_data(source.m_data) | |
| 48 { | |
| 49 source.m_data = 0; | |
| 50 } | |
| 51 ~TryMallocReturnValue() { ASSERT(!m_data); } | |
| 52 template <typename T> bool getValue(T& data) WARN_UNUSED_RETURN; | |
| 53 template <typename T> operator PossiblyNull<T>() | |
| 54 { | |
| 55 T value; | |
| 56 getValue(value); | |
| 57 return PossiblyNull<T>(value); | |
| 58 } | |
| 59 private: | |
| 60 mutable void* m_data; | |
| 61 }; | |
| 62 | |
| 63 template <typename T> bool TryMallocReturnValue::getValue(T& data) | |
| 64 { | |
| 65 union u { void* data; T target; } res; | |
| 66 res.data = m_data; | |
| 67 data = res.target; | |
| 68 bool returnValue = !!m_data; | |
| 69 m_data = 0; | |
| 70 return returnValue; | |
| 71 } | |
| 72 | |
| 73 WTF_EXPORT TryMallocReturnValue tryFastMalloc(size_t n); | |
| 74 WTF_EXPORT TryMallocReturnValue tryFastZeroedMalloc(size_t n); | |
| 75 WTF_EXPORT TryMallocReturnValue tryFastCalloc(size_t n_elements, size_t elem
ent_size); | |
| 76 WTF_EXPORT TryMallocReturnValue tryFastRealloc(void* p, size_t n); | |
| 77 | |
| 78 WTF_EXPORT void fastFree(void*); | 37 WTF_EXPORT void fastFree(void*); |
| 79 | 38 |
| 80 #ifndef NDEBUG | 39 #ifndef NDEBUG |
| 81 WTF_EXPORT void fastMallocForbid(); | 40 WTF_EXPORT void fastMallocForbid(); |
| 82 WTF_EXPORT void fastMallocAllow(); | 41 WTF_EXPORT void fastMallocAllow(); |
| 83 #endif | 42 #endif |
| 84 | 43 |
| 85 WTF_EXPORT void releaseFastMallocFreeMemory(); | 44 WTF_EXPORT void releaseFastMallocFreeMemory(); |
| 86 | 45 |
| 87 struct FastMallocStatistics { | 46 struct FastMallocStatistics { |
| 88 size_t reservedVMBytes; | 47 size_t reservedVMBytes; |
| 89 size_t committedVMBytes; | 48 size_t committedVMBytes; |
| 90 size_t freeListBytes; | 49 size_t freeListBytes; |
| 91 }; | 50 }; |
| 92 WTF_EXPORT FastMallocStatistics fastMallocStatistics(); | 51 WTF_EXPORT FastMallocStatistics fastMallocStatistics(); |
| 93 | 52 |
| 94 // This defines a type which holds an unsigned integer and is the same | 53 // This defines a type which holds an unsigned integer and is the same |
| 95 // size as the minimally aligned memory allocation. | 54 // size as the minimally aligned memory allocation. |
| 96 typedef unsigned long long AllocAlignmentInteger; | 55 typedef unsigned long long AllocAlignmentInteger; |
| 97 | 56 |
| 98 namespace Internal { | |
| 99 enum AllocType { // Start with an unusual number inst
ead of zero, because zero is common. | |
| 100 AllocTypeMalloc = 0x375d6750, // Encompasses fastMalloc, fastZeroe
dMalloc, fastCalloc, fastRealloc. | |
| 101 AllocTypeClassNew, // Encompasses class operator new fr
om FastAllocBase. | |
| 102 AllocTypeClassNewArray, // Encompasses class operator new[]
from FastAllocBase. | |
| 103 AllocTypeFastNew, // Encompasses fastNew. | |
| 104 AllocTypeFastNewArray, // Encompasses fastNewArray. | |
| 105 AllocTypeNew, // Encompasses global operator new. | |
| 106 AllocTypeNewArray // Encompasses global operator new[]
. | |
| 107 }; | |
| 108 | |
| 109 enum { | |
| 110 ValidationPrefix = 0xf00df00d, | |
| 111 ValidationSuffix = 0x0badf00d | |
| 112 }; | |
| 113 | |
| 114 typedef unsigned ValidationTag; | |
| 115 | |
| 116 struct ValidationHeader { | |
| 117 AllocType m_type; | |
| 118 unsigned m_size; | |
| 119 ValidationTag m_prefix; | |
| 120 unsigned m_alignment; | |
| 121 }; | |
| 122 | |
| 123 static const int ValidationBufferSize = sizeof(ValidationHeader) + sizeo
f(ValidationTag); | |
| 124 } | |
| 125 | |
| 126 #if ENABLE(WTF_MALLOC_VALIDATION) | |
| 127 | |
| 128 // Malloc validation is a scheme whereby a tag is attached to an | |
| 129 // allocation which identifies how it was originally allocated. | |
| 130 // This allows us to verify that the freeing operation matches the | |
| 131 // allocation operation. If memory is allocated with operator new[] | |
| 132 // but freed with free or delete, this system would detect that. | |
| 133 // In the implementation here, the tag is an integer prepended to | |
| 134 // the allocation memory which is assigned one of the AllocType | |
| 135 // enumeration values. An alternative implementation of this | |
| 136 // scheme could store the tag somewhere else or ignore it. | |
| 137 // Users of FastMalloc don't need to know or care how this tagging | |
| 138 // is implemented. | |
| 139 | |
| 140 namespace Internal { | |
| 141 | |
| 142 // Handle a detected alloc/free mismatch. By default this calls CRASH(). | |
| 143 void fastMallocMatchFailed(void* p); | |
| 144 | |
| 145 inline ValidationHeader* fastMallocValidationHeader(void* p) | |
| 146 { | |
| 147 return reinterpret_cast<ValidationHeader*>(static_cast<char*>(p) - s
izeof(ValidationHeader)); | |
| 148 } | |
| 149 | |
| 150 inline ValidationTag* fastMallocValidationSuffix(void* p) | |
| 151 { | |
| 152 ValidationHeader* header = fastMallocValidationHeader(p); | |
| 153 if (header->m_prefix != static_cast<unsigned>(ValidationPrefix)) | |
| 154 fastMallocMatchFailed(p); | |
| 155 | |
| 156 return reinterpret_cast<ValidationTag*>(static_cast<char*>(p) + head
er->m_size); | |
| 157 } | |
| 158 | |
| 159 // Return the AllocType tag associated with the allocated block p. | |
| 160 inline AllocType fastMallocMatchValidationType(void* p) | |
| 161 { | |
| 162 return fastMallocValidationHeader(p)->m_type; | |
| 163 } | |
| 164 | |
| 165 // Set the AllocType tag to be associaged with the allocated block p. | |
| 166 inline void setFastMallocMatchValidationType(void* p, AllocType allocTyp
e) | |
| 167 { | |
| 168 fastMallocValidationHeader(p)->m_type = allocType; | |
| 169 } | |
| 170 | |
| 171 } // namespace Internal | |
| 172 | |
| 173 // This is a higher level function which is used by FastMalloc-using code. | |
| 174 inline void fastMallocMatchValidateMalloc(void* p, Internal::AllocType alloc
Type) | |
| 175 { | |
| 176 if (!p) | |
| 177 return; | |
| 178 | |
| 179 Internal::setFastMallocMatchValidationType(p, allocType); | |
| 180 } | |
| 181 | |
| 182 // This is a higher level function which is used by FastMalloc-using code. | |
| 183 inline void fastMallocMatchValidateFree(void* p, Internal::AllocType) | |
| 184 { | |
| 185 if (!p) | |
| 186 return; | |
| 187 | |
| 188 Internal::ValidationHeader* header = Internal::fastMallocValidationHeade
r(p); | |
| 189 if (header->m_prefix != static_cast<unsigned>(Internal::ValidationPrefix
)) | |
| 190 Internal::fastMallocMatchFailed(p); | |
| 191 | |
| 192 if (*Internal::fastMallocValidationSuffix(p) != Internal::ValidationSuff
ix) | |
| 193 Internal::fastMallocMatchFailed(p); | |
| 194 | |
| 195 Internal::setFastMallocMatchValidationType(p, Internal::AllocTypeMalloc)
; // Set it to this so that fastFree thinks it's OK. | |
| 196 } | |
| 197 | |
| 198 inline void fastMallocValidate(void* p) | |
| 199 { | |
| 200 if (!p) | |
| 201 return; | |
| 202 | |
| 203 Internal::ValidationHeader* header = Internal::fastMallocValidationHeade
r(p); | |
| 204 if (header->m_prefix != static_cast<unsigned>(Internal::ValidationPrefix
)) | |
| 205 Internal::fastMallocMatchFailed(p); | |
| 206 | |
| 207 if (*Internal::fastMallocValidationSuffix(p) != Internal::ValidationSuff
ix) | |
| 208 Internal::fastMallocMatchFailed(p); | |
| 209 } | |
| 210 | |
| 211 #else | |
| 212 | |
| 213 inline void fastMallocMatchValidateMalloc(void*, Internal::AllocType) | |
| 214 { | |
| 215 } | |
| 216 | |
| 217 inline void fastMallocMatchValidateFree(void*, Internal::AllocType) | |
| 218 { | |
| 219 } | |
| 220 | |
| 221 #endif | |
| 222 | |
| 223 } // namespace WTF | 57 } // namespace WTF |
| 224 | 58 |
| 225 using WTF::fastCalloc; | 59 using WTF::fastCalloc; |
| 226 using WTF::fastFree; | 60 using WTF::fastFree; |
| 227 using WTF::fastMalloc; | 61 using WTF::fastMalloc; |
| 228 using WTF::fastMallocGoodSize; | 62 using WTF::fastMallocGoodSize; |
| 229 using WTF::fastRealloc; | 63 using WTF::fastRealloc; |
| 230 using WTF::fastStrDup; | 64 using WTF::fastStrDup; |
| 231 using WTF::fastZeroedMalloc; | 65 using WTF::fastZeroedMalloc; |
| 232 using WTF::tryFastCalloc; | |
| 233 using WTF::tryFastMalloc; | |
| 234 using WTF::tryFastRealloc; | |
| 235 using WTF::tryFastZeroedMalloc; | |
| 236 | 66 |
| 237 #ifndef NDEBUG | 67 #ifndef NDEBUG |
| 238 using WTF::fastMallocForbid; | 68 using WTF::fastMallocForbid; |
| 239 using WTF::fastMallocAllow; | 69 using WTF::fastMallocAllow; |
| 240 #endif | 70 #endif |
| 241 | 71 |
| 242 #endif /* WTF_FastMalloc_h */ | 72 #endif /* WTF_FastMalloc_h */ |
| OLD | NEW |