1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
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
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
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
35 #include <new> // for std::bad_alloc
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);
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
);
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
);
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
);
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
);
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
);
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
);
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);
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
124 size_t moz_malloc_usable_size(void* ptr
) {
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)
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
);
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;