Backed out changeset c22053f7eb41 (bug 1917536) for causing bug 1923376.
[gecko.git] / memory / mozalloc / mozalloc.cpp
blobaef8ab943a69b939316982544772960eea82ca92
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/. */
8 #include <stddef.h> // for size_t
10 #if defined(MALLOC_H)
11 # include MALLOC_H // for memalign, malloc_size, malloc_us
12 #endif // if defined(MALLOC_H)
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.
18 # include <stdlib.h> // for malloc, free
19 # if defined(XP_UNIX)
20 # include <unistd.h>
21 # endif // if defined(XP_UNIX)
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
32 #endif
34 #include <errno.h>
35 #include <new> // for std::bad_alloc
36 #include <cstring>
38 #include <sys/types.h>
40 #include "mozilla/Assertions.h"
41 #include "mozilla/CheckedInt.h"
42 #include "mozilla/Likely.h"
43 #include "mozilla/mozalloc.h"
44 #include "mozilla/mozalloc_oom.h" // for mozalloc_handle_oom
46 #if defined(MOZ_MEMORY)
47 MOZ_MEMORY_API char* strdup_impl(const char*);
48 MOZ_MEMORY_API char* strndup_impl(const char*, size_t);
49 #endif
51 void* moz_xmalloc(size_t size) {
52 void* ptr = malloc_impl(size);
53 if (MOZ_UNLIKELY(!ptr && size)) {
54 mozalloc_handle_oom(size);
55 return moz_xmalloc(size);
57 return ptr;
60 void* moz_xcalloc(size_t nmemb, size_t size) {
61 void* ptr = calloc_impl(nmemb, size);
62 if (MOZ_UNLIKELY(!ptr && nmemb && size)) {
63 mozilla::CheckedInt<size_t> totalSize =
64 mozilla::CheckedInt<size_t>(nmemb) * size;
65 mozalloc_handle_oom(totalSize.isValid() ? totalSize.value() : SIZE_MAX);
66 return moz_xcalloc(nmemb, size);
68 return ptr;
71 void* moz_xrealloc(void* ptr, size_t size) {
72 void* newptr = realloc_impl(ptr, size);
73 if (MOZ_UNLIKELY(!newptr && size)) {
74 mozalloc_handle_oom(size);
75 return moz_xrealloc(ptr, size);
77 return newptr;
80 char* moz_xstrdup(const char* str) {
81 char* dup = strdup_impl(str);
82 if (MOZ_UNLIKELY(!dup)) {
83 mozalloc_handle_oom(0);
84 return moz_xstrdup(str);
86 return dup;
89 #if defined(HAVE_STRNDUP)
90 char* moz_xstrndup(const char* str, size_t strsize) {
91 char* dup = strndup_impl(str, strsize);
92 if (MOZ_UNLIKELY(!dup)) {
93 mozalloc_handle_oom(strsize);
94 return moz_xstrndup(str, strsize);
96 return dup;
98 #endif // if defined(HAVE_STRNDUP)
100 void* moz_xmemdup(const void* ptr, size_t size) {
101 void* newPtr = moz_xmalloc(size);
102 memcpy(newPtr, ptr, size);
103 return newPtr;
106 #ifndef __wasm__
107 # ifndef HAVE_MEMALIGN
108 // We always have a definition of memalign, but system headers don't
109 // necessarily come with a declaration.
110 extern "C" void* memalign(size_t, size_t);
111 # endif
113 void* moz_xmemalign(size_t boundary, size_t size) {
114 void* ptr = memalign_impl(boundary, size);
115 if (MOZ_UNLIKELY(!ptr && EINVAL != errno)) {
116 mozalloc_handle_oom(size);
117 return moz_xmemalign(boundary, size);
119 // non-NULL ptr or errno == EINVAL
120 return ptr;
122 #endif
124 size_t moz_malloc_usable_size(void* ptr) {
125 if (!ptr) return 0;
127 #if defined(XP_DARWIN)
128 return malloc_size(ptr);
129 #elif defined(HAVE_MALLOC_USABLE_SIZE) || defined(MOZ_MEMORY)
130 return malloc_usable_size_impl(ptr);
131 #elif defined(XP_WIN)
132 return _msize(ptr);
133 #else
134 return 0;
135 #endif
138 size_t moz_malloc_size_of(const void* ptr) {
139 return moz_malloc_usable_size((void*)ptr);
142 #if defined(MOZ_MEMORY)
143 # include "mozjemalloc_types.h"
144 // mozmemory.h declares jemalloc_ptr_info(), but including that header in this
145 // file is complicated. So we just redeclare it here instead, and include
146 // mozjemalloc_types.h for jemalloc_ptr_info_t.
147 MOZ_JEMALLOC_API void jemalloc_ptr_info(const void* ptr,
148 jemalloc_ptr_info_t* info);
149 #endif
151 size_t moz_malloc_enclosing_size_of(const void* ptr) {
152 #if defined(MOZ_MEMORY)
153 jemalloc_ptr_info_t info;
154 jemalloc_ptr_info(ptr, &info);
155 return jemalloc_ptr_is_live(&info) ? info.size : 0;
156 #else
157 return 0;
158 #endif