tor-browser

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

mozalloc.cpp (4226B)


      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 #include <stddef.h>  // for size_t
      9 
     10 #if defined(MALLOC_H)
     11 #  include MALLOC_H  // for memalign, malloc_size, malloc_us
     12 #endif               // if defined(MALLOC_H)
     13 
     14 #if !defined(MOZ_MEMORY)
     15 // When jemalloc is disabled, or when building the static runtime variant,
     16 // we need not to use the suffixes.
     17 
     18 #  include <stdlib.h>  // for malloc, free
     19 #  if defined(XP_UNIX)
     20 #    include <unistd.h>
     21 #  endif  // if defined(XP_UNIX)
     22 
     23 #  define malloc_impl malloc
     24 #  define calloc_impl calloc
     25 #  define realloc_impl realloc
     26 #  define free_impl free
     27 #  define memalign_impl memalign
     28 #  define malloc_usable_size_impl malloc_usable_size
     29 #  define strdup_impl strdup
     30 #  define strndup_impl strndup
     31 
     32 #endif
     33 
     34 #include <errno.h>
     35 #include <new>  // for std::bad_alloc
     36 #include <cstring>
     37 
     38 #include <sys/types.h>
     39 
     40 #include "mozilla/CheckedInt.h"
     41 #include "mozilla/Likely.h"
     42 #include "mozilla/mozalloc.h"
     43 #include "mozilla/mozalloc_oom.h"  // for mozalloc_handle_oom
     44 
     45 #if defined(MOZ_MEMORY)
     46 MOZ_MEMORY_API char* strdup_impl(const char*);
     47 MOZ_MEMORY_API char* strndup_impl(const char*, size_t);
     48 #endif
     49 
     50 void* moz_xmalloc(size_t size) {
     51  void* ptr = malloc_impl(size);
     52  if (MOZ_UNLIKELY(!ptr && size)) {
     53    mozalloc_handle_oom(size);
     54    return moz_xmalloc(size);
     55  }
     56  return ptr;
     57 }
     58 
     59 void* moz_xcalloc(size_t nmemb, size_t size) {
     60  void* ptr = calloc_impl(nmemb, size);
     61  if (MOZ_UNLIKELY(!ptr && nmemb && size)) {
     62    mozilla::CheckedInt<size_t> totalSize =
     63        mozilla::CheckedInt<size_t>(nmemb) * size;
     64    mozalloc_handle_oom(totalSize.isValid() ? totalSize.value() : SIZE_MAX);
     65    return moz_xcalloc(nmemb, size);
     66  }
     67  return ptr;
     68 }
     69 
     70 void* moz_xrealloc(void* ptr, size_t size) {
     71  void* newptr = realloc_impl(ptr, size);
     72  if (MOZ_UNLIKELY(!newptr && size)) {
     73    mozalloc_handle_oom(size);
     74    return moz_xrealloc(ptr, size);
     75  }
     76  return newptr;
     77 }
     78 
     79 char* moz_xstrdup(const char* str) {
     80  char* dup = strdup_impl(str);
     81  if (MOZ_UNLIKELY(!dup)) {
     82    mozalloc_handle_oom(0);
     83    return moz_xstrdup(str);
     84  }
     85  return dup;
     86 }
     87 
     88 #if defined(HAVE_STRNDUP)
     89 char* moz_xstrndup(const char* str, size_t strsize) {
     90  char* dup = strndup_impl(str, strsize);
     91  if (MOZ_UNLIKELY(!dup)) {
     92    mozalloc_handle_oom(strsize);
     93    return moz_xstrndup(str, strsize);
     94  }
     95  return dup;
     96 }
     97 #endif  // if defined(HAVE_STRNDUP)
     98 
     99 void* moz_xmemdup(const void* ptr, size_t size) {
    100  void* newPtr = moz_xmalloc(size);
    101  memcpy(newPtr, ptr, size);
    102  return newPtr;
    103 }
    104 
    105 #ifndef __wasm__
    106 #  ifndef HAVE_MEMALIGN
    107 // We always have a definition of memalign, but system headers don't
    108 // necessarily come with a declaration.
    109 extern "C" void* memalign(size_t, size_t);
    110 #  endif
    111 
    112 void* moz_xmemalign(size_t boundary, size_t size) {
    113  void* ptr = memalign_impl(boundary, size);
    114  if (MOZ_UNLIKELY(!ptr && EINVAL != errno)) {
    115    mozalloc_handle_oom(size);
    116    return moz_xmemalign(boundary, size);
    117  }
    118  // non-NULL ptr or errno == EINVAL
    119  return ptr;
    120 }
    121 #endif
    122 
    123 size_t moz_malloc_usable_size(void* ptr) {
    124  if (!ptr) return 0;
    125 
    126 #if defined(XP_DARWIN)
    127  return malloc_size(ptr);
    128 #elif defined(HAVE_MALLOC_USABLE_SIZE) || defined(MOZ_MEMORY)
    129  return malloc_usable_size_impl(ptr);
    130 #elif defined(XP_WIN)
    131  return _msize(ptr);
    132 #else
    133  return 0;
    134 #endif
    135 }
    136 
    137 size_t moz_malloc_size_of(const void* ptr) {
    138  return moz_malloc_usable_size((void*)ptr);
    139 }
    140 
    141 #if defined(MOZ_MEMORY)
    142 #  include "mozjemalloc_types.h"
    143 // mozmemory.h declares jemalloc_ptr_info(), but including that header in this
    144 // file is complicated. So we just redeclare it here instead, and include
    145 // mozjemalloc_types.h for jemalloc_ptr_info_t.
    146 MOZ_JEMALLOC_API void jemalloc_ptr_info(const void* ptr,
    147                                        jemalloc_ptr_info_t* info);
    148 #endif
    149 
    150 size_t moz_malloc_enclosing_size_of(const void* ptr) {
    151 #if defined(MOZ_MEMORY)
    152  jemalloc_ptr_info_t info;
    153  jemalloc_ptr_info(ptr, &info);
    154  return jemalloc_ptr_is_live(&info) ? info.size : 0;
    155 #else
    156  return 0;
    157 #endif
    158 }