memory/mozalloc/mozalloc.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * vim: sw=4 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/. */
     8 #include <errno.h>
     9 #include <new>                  // for std::bad_alloc
    10 #include <string.h>
    12 #include <sys/types.h>
    14 #if defined(MALLOC_H)
    15 #  include MALLOC_H             // for memalign, valloc, malloc_size, malloc_usable_size
    16 #endif // if defined(MALLOC_H)
    17 #include <stddef.h>             // for size_t
    18 #include <stdlib.h>             // for malloc, free
    19 #if defined(XP_UNIX)
    20 #  include <unistd.h>           // for valloc on *BSD
    21 #endif //if defined(XP_UNIX)
    23 #if defined(XP_WIN)
    24 #  define MOZALLOC_EXPORT __declspec(dllexport)
    25 #endif
    27 #include "mozilla/mozalloc.h"
    28 #include "mozilla/mozalloc_oom.h"  // for mozalloc_handle_oom
    30 /* Windows doesn't have malloc_usable_size, but jemalloc has */
    31 #if defined(MOZ_MEMORY_WINDOWS)
    32 extern "C" size_t malloc_usable_size(const void *ptr);
    33 #endif
    35 #ifdef __GNUC__
    36 #define LIKELY(x)    (__builtin_expect(!!(x), 1))
    37 #define UNLIKELY(x)  (__builtin_expect(!!(x), 0))
    38 #else
    39 #define LIKELY(x)    (x)
    40 #define UNLIKELY(x)  (x)
    41 #endif
    43 void
    44 moz_free(void* ptr)
    45 {
    46     free(ptr);
    47 }
    49 void*
    50 moz_xmalloc(size_t size)
    51 {
    52     void* ptr = malloc(size);
    53     if (UNLIKELY(!ptr && size)) {
    54         mozalloc_handle_oom(size);
    55         return moz_xmalloc(size);
    56     }
    57     return ptr;
    58 }
    59 void*
    60 moz_malloc(size_t size)
    61 {
    62     return malloc(size);
    63 }
    65 void*
    66 moz_xcalloc(size_t nmemb, size_t size)
    67 {
    68     void* ptr = calloc(nmemb, size);
    69     if (UNLIKELY(!ptr && nmemb && size)) {
    70         mozalloc_handle_oom(size);
    71         return moz_xcalloc(nmemb, size);
    72     }
    73     return ptr;
    74 }
    75 void*
    76 moz_calloc(size_t nmemb, size_t size)
    77 {
    78     return calloc(nmemb, size);
    79 }
    81 void*
    82 moz_xrealloc(void* ptr, size_t size)
    83 {
    84     void* newptr = realloc(ptr, size);
    85     if (UNLIKELY(!newptr && size)) {
    86         mozalloc_handle_oom(size);
    87         return moz_xrealloc(ptr, size);
    88     }
    89     return newptr;
    90 }
    91 void*
    92 moz_realloc(void* ptr, size_t size)
    93 {
    94     return realloc(ptr, size);
    95 }
    97 char*
    98 moz_xstrdup(const char* str)
    99 {
   100     char* dup = strdup(str);
   101     if (UNLIKELY(!dup)) {
   102         mozalloc_handle_oom(0);
   103         return moz_xstrdup(str);
   104     }
   105     return dup;
   106 }
   107 char*
   108 moz_strdup(const char* str)
   109 {
   110     return strdup(str);
   111 }
   113 #if defined(HAVE_STRNDUP)
   114 char*
   115 moz_xstrndup(const char* str, size_t strsize)
   116 {
   117     char* dup = strndup(str, strsize);
   118     if (UNLIKELY(!dup)) {
   119         mozalloc_handle_oom(strsize);
   120         return moz_xstrndup(str, strsize);
   121     }
   122     return dup;
   123 }
   124 char*
   125 moz_strndup(const char* str, size_t strsize)
   126 {
   127     return strndup(str, strsize);
   128 }
   129 #endif  // if defined(HAVE_STRNDUP)
   131 #if defined(HAVE_POSIX_MEMALIGN)
   132 int
   133 moz_xposix_memalign(void **ptr, size_t alignment, size_t size)
   134 {
   135     int err = posix_memalign(ptr, alignment, size);
   136     if (UNLIKELY(err && ENOMEM == err)) {
   137         mozalloc_handle_oom(size);
   138         return moz_xposix_memalign(ptr, alignment, size);
   139     }
   140     // else: (0 == err) or (EINVAL == err)
   141     return err;
   142 }
   143 int
   144 moz_posix_memalign(void **ptr, size_t alignment, size_t size)
   145 {
   146     int code = posix_memalign(ptr, alignment, size);
   147     if (code)
   148         return code;
   150 #if defined(XP_MACOSX)
   151     // Workaround faulty OSX posix_memalign, which provides memory with the
   152     // incorrect alignment sometimes, but returns 0 as if nothing was wrong.
   153     size_t mask = alignment - 1;
   154     if (((size_t)(*ptr) & mask) != 0) {
   155         void* old = *ptr;
   156         code = moz_posix_memalign(ptr, alignment, size);
   157         free(old);
   158     }
   159 #endif
   161     return code;
   163 }
   164 #endif // if defined(HAVE_POSIX_MEMALIGN)
   166 #if defined(HAVE_MEMALIGN)
   167 void*
   168 moz_xmemalign(size_t boundary, size_t size)
   169 {
   170     void* ptr = memalign(boundary, size);
   171     if (UNLIKELY(!ptr && EINVAL != errno)) {
   172         mozalloc_handle_oom(size);
   173         return moz_xmemalign(boundary, size);
   174     }
   175     // non-NULL ptr or errno == EINVAL
   176     return ptr;
   177 }
   178 void*
   179 moz_memalign(size_t boundary, size_t size)
   180 {
   181     return memalign(boundary, size);
   182 }
   183 #endif // if defined(HAVE_MEMALIGN)
   185 #if defined(HAVE_VALLOC)
   186 void*
   187 moz_xvalloc(size_t size)
   188 {
   189     void* ptr = valloc(size);
   190     if (UNLIKELY(!ptr)) {
   191         mozalloc_handle_oom(size);
   192         return moz_xvalloc(size);
   193     }
   194     return ptr;
   195 }
   196 void*
   197 moz_valloc(size_t size)
   198 {
   199     return valloc(size);
   200 }
   201 #endif // if defined(HAVE_VALLOC)
   203 size_t
   204 moz_malloc_usable_size(void *ptr)
   205 {
   206     if (!ptr)
   207         return 0;
   209 #if defined(XP_MACOSX)
   210     return malloc_size(ptr);
   211 #elif defined(HAVE_MALLOC_USABLE_SIZE) || defined(MOZ_MEMORY)
   212     return malloc_usable_size(ptr);
   213 #elif defined(XP_WIN)
   214     return _msize(ptr);
   215 #else
   216     return 0;
   217 #endif
   218 }
   220 size_t moz_malloc_size_of(const void *ptr)
   221 {
   222     return moz_malloc_usable_size((void *)ptr);
   223 }
   225 namespace mozilla {
   227 const fallible_t fallible = fallible_t();
   229 } // namespace mozilla

mercurial