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.

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

mercurial