tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

mozalloc.h (6184B)


      1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: sw=2 ts=4 et :
      3 */
      4 /* This Source Code Form is subject to the terms of the Mozilla Public
      5 * License, v. 2.0. If a copy of the MPL was not distributed with this
      6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      7 
      8 #ifndef mozilla_mozalloc_h
      9 #define mozilla_mozalloc_h
     10 
     11 /*
     12 * https://bugzilla.mozilla.org/show_bug.cgi?id=427099
     13 */
     14 
     15 #if defined(__cplusplus)
     16 #  include <new>
     17 // Since libstdc++ 6, including the C headers (e.g. stdlib.h) instead of the
     18 // corresponding C++ header (e.g. cstdlib) can cause confusion in C++ code
     19 // using things defined there. Specifically, with stdlib.h, the use of abs()
     20 // in gfx/graphite2/src/inc/UtfCodec.h somehow ends up picking the wrong abs()
     21 #  include <cstdlib>
     22 #else
     23 #  include <stdlib.h>
     24 #endif
     25 
     26 #if defined(MOZ_MEMORY) && defined(IMPL_MFBT)
     27 #  define MOZ_MEMORY_IMPL
     28 #  include "mozmemory_wrap.h"
     29 #  define MALLOC_FUNCS MALLOC_FUNCS_MALLOC
     30 // See mozmemory_wrap.h for more details. Files that are part of libmozglue,
     31 // need to use _impl suffixes, which is becoming cumbersome. We'll have to use
     32 // something like a malloc.h wrapper and allow the use of the functions without
     33 // a _impl suffix. In the meanwhile, this is enough to get by for C++ code.
     34 #  define NOTHROW_MALLOC_DECL(name, return_type, ...) \
     35    MOZ_MEMORY_API return_type name##_impl(__VA_ARGS__) noexcept(true);
     36 #  define MALLOC_DECL(name, return_type, ...) \
     37    MOZ_MEMORY_API return_type name##_impl(__VA_ARGS__);
     38 #  include "malloc_decls.h"
     39 #endif
     40 
     41 #if defined(__cplusplus)
     42 #  include "mozilla/mozalloc_abort.h"
     43 #  include "mozilla/CheckedArithmetic.h"
     44 #  include "mozilla/Likely.h"
     45 #endif
     46 #include "mozilla/Attributes.h"
     47 #include "mozilla/Types.h"
     48 
     49 MOZ_BEGIN_EXTERN_C
     50 
     51 /*
     52 * We need to use malloc_impl and free_impl in this file when they are
     53 * defined, because of how mozglue.dll is linked on Windows, where using
     54 * malloc/free would end up using the symbols from the MSVCRT instead of
     55 * ours.
     56 */
     57 #ifndef free_impl
     58 #  define free_impl free
     59 #  define free_impl_
     60 #endif
     61 #ifndef malloc_impl
     62 #  define malloc_impl malloc
     63 #  define malloc_impl_
     64 #endif
     65 
     66 /*
     67 * Each declaration below is analogous to a "standard" allocation
     68 * function, except that the out-of-memory handling is made explicit.
     69 * The |moz_x| versions will never return a NULL pointer; if memory
     70 * is exhausted, they abort.  The |moz_| versions may return NULL
     71 * pointers if memory is exhausted: their return value must be checked.
     72 *
     73 * All these allocation functions are *guaranteed* to return a pointer
     74 * to memory allocated in such a way that that memory can be freed by
     75 * passing that pointer to |free()|.
     76 */
     77 
     78 MFBT_API void* moz_xmalloc(size_t size) MOZ_INFALLIBLE_ALLOCATOR;
     79 
     80 MFBT_API void* moz_xcalloc(size_t nmemb, size_t size) MOZ_INFALLIBLE_ALLOCATOR;
     81 
     82 MFBT_API void* moz_xrealloc(void* ptr, size_t size) MOZ_INFALLIBLE_ALLOCATOR;
     83 
     84 MFBT_API char* moz_xstrdup(const char* str) MOZ_INFALLIBLE_ALLOCATOR;
     85 
     86 #if defined(HAVE_STRNDUP)
     87 MFBT_API char* moz_xstrndup(const char* str,
     88                            size_t strsize) MOZ_INFALLIBLE_ALLOCATOR;
     89 #endif /* if defined(HAVE_STRNDUP) */
     90 
     91 MFBT_API void* moz_xmemdup(const void* ptr,
     92                           size_t size) MOZ_INFALLIBLE_ALLOCATOR;
     93 
     94 MFBT_API void* moz_xmemalign(size_t boundary,
     95                             size_t size) MOZ_INFALLIBLE_ALLOCATOR;
     96 
     97 MFBT_API size_t moz_malloc_usable_size(void* ptr);
     98 
     99 MFBT_API size_t moz_malloc_size_of(const void* ptr);
    100 
    101 /*
    102 * Like moz_malloc_size_of(), but works reliably with interior pointers, i.e.
    103 * pointers into the middle of a live allocation.
    104 */
    105 MFBT_API size_t moz_malloc_enclosing_size_of(const void* ptr);
    106 
    107 MOZ_END_EXTERN_C
    108 
    109 #ifdef __cplusplus
    110 
    111 /* NB: This is defined with MFBT_API just to silence vacuous warnings
    112 * about symbol visibility on OS X/gcc.
    113 * These symbols are force-inline mainly for performance reasons, and
    114 * not exported. While the standard doesn't allow that, we are in a
    115 * controlled environment where the issues the standard tries to
    116 * prevent don't apply, and we can't end up in situations where
    117 * operator new and operator delete are inconsistent. */
    118 #  ifdef __clang__
    119 #    pragma clang diagnostic push
    120 #    pragma clang diagnostic ignored "-Winline-new-delete"
    121 #  endif
    122 
    123 #  if defined(XP_MACOSX)
    124 #    define MOZALLOC_EXPORT_NEW MFBT_API MOZ_ALWAYS_INLINE_EVEN_DEBUG
    125 #  else
    126 #    define MOZALLOC_EXPORT_NEW MOZ_ALWAYS_INLINE_EVEN_DEBUG
    127 #  endif
    128 
    129 #  include "mozilla/cxxalloc.h"
    130 #  ifdef __clang__
    131 #    pragma clang diagnostic pop
    132 #  endif
    133 
    134 /*
    135 * This policy is identical to MallocAllocPolicy, except it uses
    136 * moz_xmalloc/moz_xcalloc/moz_xrealloc instead of
    137 * malloc/calloc/realloc.
    138 */
    139 class InfallibleAllocPolicy {
    140 public:
    141  template <typename T>
    142  T* maybe_pod_malloc(size_t aNumElems) {
    143    return pod_malloc<T>(aNumElems);
    144  }
    145 
    146  template <typename T>
    147  T* maybe_pod_calloc(size_t aNumElems) {
    148    return pod_calloc<T>(aNumElems);
    149  }
    150 
    151  template <typename T>
    152  T* maybe_pod_realloc(T* aPtr, size_t aOldSize, size_t aNewSize) {
    153    return pod_realloc<T>(aPtr, aOldSize, aNewSize);
    154  }
    155 
    156  template <typename T>
    157  T* pod_malloc(size_t aNumElems) {
    158    size_t size;
    159    if (MOZ_UNLIKELY(!mozilla::SafeMul(aNumElems, sizeof(T), &size))) {
    160      reportAllocOverflow();
    161    }
    162    return static_cast<T*>(moz_xmalloc(size));
    163  }
    164 
    165  template <typename T>
    166  T* pod_calloc(size_t aNumElems) {
    167    return static_cast<T*>(moz_xcalloc(aNumElems, sizeof(T)));
    168  }
    169 
    170  template <typename T>
    171  T* pod_realloc(T* aPtr, size_t aOldSize, size_t aNewSize) {
    172    size_t size;
    173    if (MOZ_UNLIKELY(!mozilla::SafeMul(aNewSize, sizeof(T), &size))) {
    174      reportAllocOverflow();
    175    }
    176    return static_cast<T*>(moz_xrealloc(aPtr, size));
    177  }
    178 
    179  template <typename T>
    180  void free_(T* aPtr, size_t aNumElems = 0) {
    181    free_impl(aPtr);
    182  }
    183 
    184  void reportAllocOverflow() const { mozalloc_abort("alloc overflow"); }
    185 
    186  bool checkSimulatedOOM() const { return true; }
    187 };
    188 
    189 #endif /* ifdef __cplusplus */
    190 
    191 #ifdef malloc_impl_
    192 #  undef malloc_impl_
    193 #  undef malloc_impl
    194 #endif
    195 #ifdef free_impl_
    196 #  undef free_impl_
    197 #  undef free_impl
    198 #endif
    199 
    200 #endif /* ifndef mozilla_mozalloc_h */