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