JavaScriptCore/wtf/FastMalloc.h
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     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 "PossiblyNull.h"
       
    26 #include <stdlib.h>
       
    27 #include <new>
       
    28 
       
    29 namespace WTF {
       
    30 
       
    31     // These functions call CRASH() if an allocation fails.
       
    32     void* fastMalloc(size_t);
       
    33     void* fastZeroedMalloc(size_t);
       
    34     void* fastCalloc(size_t numElements, size_t elementSize);
       
    35     void* fastRealloc(void*, size_t);
       
    36     char* fastStrDup(const char*);
       
    37     size_t fastMallocSize(const void*);
       
    38 
       
    39     struct TryMallocReturnValue {
       
    40         TryMallocReturnValue(void* data)
       
    41             : m_data(data)
       
    42         {
       
    43         }
       
    44         TryMallocReturnValue(const TryMallocReturnValue& source)
       
    45             : m_data(source.m_data)
       
    46         {
       
    47             source.m_data = 0;
       
    48         }
       
    49         ~TryMallocReturnValue() { ASSERT(!m_data); }
       
    50         template <typename T> bool getValue(T& data) WARN_UNUSED_RETURN;
       
    51         template <typename T> operator PossiblyNull<T>()
       
    52         { 
       
    53             T value; 
       
    54             getValue(value); 
       
    55             return PossiblyNull<T>(value);
       
    56         } 
       
    57     private:
       
    58         mutable void* m_data;
       
    59     };
       
    60     
       
    61     template <typename T> bool TryMallocReturnValue::getValue(T& data)
       
    62     {
       
    63         union u { void* data; T target; } res;
       
    64         res.data = m_data;
       
    65         data = res.target;
       
    66         bool returnValue = !!m_data;
       
    67         m_data = 0;
       
    68         return returnValue;
       
    69     }
       
    70 
       
    71     TryMallocReturnValue tryFastMalloc(size_t n);
       
    72     TryMallocReturnValue tryFastZeroedMalloc(size_t n);
       
    73     TryMallocReturnValue tryFastCalloc(size_t n_elements, size_t element_size);
       
    74     TryMallocReturnValue tryFastRealloc(void* p, size_t n);
       
    75 
       
    76     void fastFree(void*);
       
    77 
       
    78 #ifndef NDEBUG    
       
    79     void fastMallocForbid();
       
    80     void fastMallocAllow();
       
    81 #endif
       
    82 
       
    83     void releaseFastMallocFreeMemory();
       
    84     
       
    85     struct FastMallocStatistics {
       
    86         size_t reservedVMBytes;
       
    87         size_t committedVMBytes;
       
    88         size_t freeListBytes;
       
    89     };
       
    90     FastMallocStatistics fastMallocStatistics();
       
    91 
       
    92     // This defines a type which holds an unsigned integer and is the same
       
    93     // size as the minimally aligned memory allocation.
       
    94     typedef unsigned long long AllocAlignmentInteger;
       
    95 
       
    96     namespace Internal {
       
    97         enum AllocType {                    // Start with an unusual number instead of zero, because zero is common.
       
    98             AllocTypeMalloc = 0x375d6750,   // Encompasses fastMalloc, fastZeroedMalloc, fastCalloc, fastRealloc.
       
    99             AllocTypeClassNew,              // Encompasses class operator new from FastAllocBase.
       
   100             AllocTypeClassNewArray,         // Encompasses class operator new[] from FastAllocBase.
       
   101             AllocTypeFastNew,               // Encompasses fastNew.
       
   102             AllocTypeFastNewArray,          // Encompasses fastNewArray.
       
   103             AllocTypeNew,                   // Encompasses global operator new.
       
   104             AllocTypeNewArray               // Encompasses global operator new[].
       
   105         };
       
   106     }
       
   107 
       
   108 #if ENABLE(FAST_MALLOC_MATCH_VALIDATION)
       
   109 
       
   110     // Malloc validation is a scheme whereby a tag is attached to an
       
   111     // allocation which identifies how it was originally allocated.
       
   112     // This allows us to verify that the freeing operation matches the
       
   113     // allocation operation. If memory is allocated with operator new[]
       
   114     // but freed with free or delete, this system would detect that.
       
   115     // In the implementation here, the tag is an integer prepended to
       
   116     // the allocation memory which is assigned one of the AllocType
       
   117     // enumeration values. An alternative implementation of this
       
   118     // scheme could store the tag somewhere else or ignore it.
       
   119     // Users of FastMalloc don't need to know or care how this tagging
       
   120     // is implemented.
       
   121 
       
   122     namespace Internal {
       
   123 
       
   124         // Return the AllocType tag associated with the allocated block p.
       
   125         inline AllocType fastMallocMatchValidationType(const void* p)
       
   126         {
       
   127             const AllocAlignmentInteger* type = static_cast<const AllocAlignmentInteger*>(p) - 1;
       
   128             return static_cast<AllocType>(*type);
       
   129         }
       
   130 
       
   131         // Return the address of the AllocType tag associated with the allocated block p.
       
   132         inline AllocAlignmentInteger* fastMallocMatchValidationValue(void* p)
       
   133         {
       
   134             return reinterpret_cast<AllocAlignmentInteger*>(static_cast<char*>(p) - sizeof(AllocAlignmentInteger));
       
   135         }
       
   136 
       
   137         // Set the AllocType tag to be associaged with the allocated block p.
       
   138         inline void setFastMallocMatchValidationType(void* p, AllocType allocType)
       
   139         {
       
   140             AllocAlignmentInteger* type = static_cast<AllocAlignmentInteger*>(p) - 1;
       
   141             *type = static_cast<AllocAlignmentInteger>(allocType);
       
   142         }
       
   143 
       
   144         // Handle a detected alloc/free mismatch. By default this calls CRASH().
       
   145         void fastMallocMatchFailed(void* p);
       
   146 
       
   147     } // namespace Internal
       
   148 
       
   149     // This is a higher level function which is used by FastMalloc-using code.
       
   150     inline void fastMallocMatchValidateMalloc(void* p, Internal::AllocType allocType)
       
   151     {
       
   152         if (!p)
       
   153             return;
       
   154 
       
   155         Internal::setFastMallocMatchValidationType(p, allocType);
       
   156     }
       
   157 
       
   158     // This is a higher level function which is used by FastMalloc-using code.
       
   159     inline void fastMallocMatchValidateFree(void* p, Internal::AllocType allocType)
       
   160     {
       
   161         if (!p)
       
   162             return;
       
   163 
       
   164         if (Internal::fastMallocMatchValidationType(p) != allocType)
       
   165             Internal::fastMallocMatchFailed(p);
       
   166         Internal::setFastMallocMatchValidationType(p, Internal::AllocTypeMalloc);  // Set it to this so that fastFree thinks it's OK.
       
   167     }
       
   168 
       
   169 #else
       
   170 
       
   171     inline void fastMallocMatchValidateMalloc(void*, Internal::AllocType)
       
   172     {
       
   173     }
       
   174 
       
   175     inline void fastMallocMatchValidateFree(void*, Internal::AllocType)
       
   176     {
       
   177     }
       
   178 
       
   179 #endif
       
   180 
       
   181 } // namespace WTF
       
   182 
       
   183 using WTF::fastCalloc;
       
   184 using WTF::fastFree;
       
   185 using WTF::fastMalloc;
       
   186 using WTF::fastMallocSize;
       
   187 using WTF::fastRealloc;
       
   188 using WTF::fastStrDup;
       
   189 using WTF::fastZeroedMalloc;
       
   190 using WTF::tryFastCalloc;
       
   191 using WTF::tryFastMalloc;
       
   192 using WTF::tryFastRealloc;
       
   193 using WTF::tryFastZeroedMalloc;
       
   194 
       
   195 #ifndef NDEBUG    
       
   196 using WTF::fastMallocForbid;
       
   197 using WTF::fastMallocAllow;
       
   198 #endif
       
   199 
       
   200 #if COMPILER(GCC) && OS(DARWIN)
       
   201 #define WTF_PRIVATE_INLINE __private_extern__ inline __attribute__((always_inline))
       
   202 #elif COMPILER(GCC)
       
   203 #define WTF_PRIVATE_INLINE inline __attribute__((always_inline))
       
   204 #elif COMPILER(MSVC) || COMPILER(RVCT)
       
   205 #define WTF_PRIVATE_INLINE __forceinline
       
   206 #else
       
   207 #define WTF_PRIVATE_INLINE inline
       
   208 #endif
       
   209 
       
   210 #if !defined(_CRTDBG_MAP_ALLOC) && !(defined(USE_SYSTEM_MALLOC) && USE_SYSTEM_MALLOC && !PLATFORM(BREWMP))
       
   211 
       
   212 // The nothrow functions here are actually not all that helpful, because fastMalloc will
       
   213 // call CRASH() rather than returning 0, and returning 0 is what nothrow is all about.
       
   214 // But since WebKit code never uses exceptions or nothrow at all, this is probably OK.
       
   215 // Long term we will adopt FastAllocBase.h everywhere, and and replace this with
       
   216 // debug-only code to make sure we don't use the system malloc via the default operator
       
   217 // new by accident.
       
   218 
       
   219 #if ENABLE(GLOBAL_FASTMALLOC_NEW)
       
   220 
       
   221 #if COMPILER(MSVC)
       
   222 #pragma warning(push)
       
   223 #pragma warning(disable: 4290) // Disable the C++ exception specification ignored warning.
       
   224 #endif
       
   225 WTF_PRIVATE_INLINE void* operator new(size_t size) throw (std::bad_alloc) { return fastMalloc(size); }
       
   226 WTF_PRIVATE_INLINE void* operator new(size_t size, const std::nothrow_t&) throw() { return fastMalloc(size); }
       
   227 WTF_PRIVATE_INLINE void operator delete(void* p) throw() { fastFree(p); }
       
   228 WTF_PRIVATE_INLINE void operator delete(void* p, const std::nothrow_t&) throw() { fastFree(p); }
       
   229 WTF_PRIVATE_INLINE void* operator new[](size_t size) throw (std::bad_alloc) { return fastMalloc(size); }
       
   230 WTF_PRIVATE_INLINE void* operator new[](size_t size, const std::nothrow_t&) throw() { return fastMalloc(size); }
       
   231 WTF_PRIVATE_INLINE void operator delete[](void* p) throw() { fastFree(p); }
       
   232 WTF_PRIVATE_INLINE void operator delete[](void* p, const std::nothrow_t&) throw() { fastFree(p); }
       
   233 #if COMPILER(MSVC)
       
   234 #pragma warning(pop)
       
   235 #endif
       
   236 
       
   237 #endif
       
   238 
       
   239 #endif
       
   240 
       
   241 #endif /* WTF_FastMalloc_h */