mozalloc.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  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/. */
  7. #include <stddef.h> // for size_t
  8. // Building with USE_STATIC_LIBS = True sets -MT instead of -MD. -MT sets _MT,
  9. // while -MD sets _MT and _DLL.
  10. #if defined(_MT) && !defined(_DLL)
  11. #define MOZ_STATIC_RUNTIME
  12. #endif
  13. #if defined(MOZ_MEMORY) && !defined(MOZ_STATIC_RUNTIME)
  14. // mozalloc.cpp is part of the same library as mozmemory, thus MOZ_MEMORY_IMPL
  15. // is needed.
  16. #define MOZ_MEMORY_IMPL
  17. #include "mozmemory_wrap.h"
  18. // See mozmemory_wrap.h for more details. This file is part of libmozglue, so
  19. // it needs to use _impl suffixes. However, with libmozglue growing, this is
  20. // becoming cumbersome, so we will likely use a malloc.h wrapper of some sort
  21. // and allow the use of the functions without a _impl suffix.
  22. #define MALLOC_DECL(name, return_type, ...) \
  23. extern "C" MOZ_MEMORY_API return_type name ## _impl(__VA_ARGS__);
  24. #define MALLOC_FUNCS MALLOC_FUNCS_MALLOC
  25. #include "malloc_decls.h"
  26. extern "C" MOZ_MEMORY_API char *strdup_impl(const char *);
  27. extern "C" MOZ_MEMORY_API char *strndup_impl(const char *, size_t);
  28. #else
  29. // When jemalloc is disabled, or when building the static runtime variant,
  30. // we need not to use the suffixes.
  31. #if defined(MALLOC_H)
  32. # include MALLOC_H // for memalign, valloc, malloc_size, malloc_us
  33. #endif // if defined(MALLOC_H)
  34. #include <stdlib.h> // for malloc, free
  35. #if defined(XP_UNIX)
  36. # include <unistd.h> // for valloc on *BSD
  37. #endif //if defined(XP_UNIX)
  38. #define malloc_impl malloc
  39. #define posix_memalign_impl posix_memalign
  40. #define calloc_impl calloc
  41. #define realloc_impl realloc
  42. #define free_impl free
  43. #define memalign_impl memalign
  44. #define valloc_impl valloc
  45. #define malloc_usable_size_impl malloc_usable_size
  46. #define strdup_impl strdup
  47. #define strndup_impl strndup
  48. #endif
  49. #include <errno.h>
  50. #include <new> // for std::bad_alloc
  51. #include <string.h>
  52. #include <sys/types.h>
  53. #include "mozilla/mozalloc.h"
  54. #include "mozilla/mozalloc_oom.h" // for mozalloc_handle_oom
  55. #ifdef __GNUC__
  56. #define LIKELY(x) (__builtin_expect(!!(x), 1))
  57. #define UNLIKELY(x) (__builtin_expect(!!(x), 0))
  58. #else
  59. #define LIKELY(x) (x)
  60. #define UNLIKELY(x) (x)
  61. #endif
  62. void*
  63. moz_xmalloc(size_t size)
  64. {
  65. void* ptr = malloc_impl(size);
  66. if (UNLIKELY(!ptr && size)) {
  67. mozalloc_handle_oom(size);
  68. return moz_xmalloc(size);
  69. }
  70. return ptr;
  71. }
  72. void*
  73. moz_xcalloc(size_t nmemb, size_t size)
  74. {
  75. void* ptr = calloc_impl(nmemb, size);
  76. if (UNLIKELY(!ptr && nmemb && size)) {
  77. mozalloc_handle_oom(size);
  78. return moz_xcalloc(nmemb, size);
  79. }
  80. return ptr;
  81. }
  82. void*
  83. moz_xrealloc(void* ptr, size_t size)
  84. {
  85. void* newptr = realloc_impl(ptr, size);
  86. if (UNLIKELY(!newptr && size)) {
  87. mozalloc_handle_oom(size);
  88. return moz_xrealloc(ptr, size);
  89. }
  90. return newptr;
  91. }
  92. char*
  93. moz_xstrdup(const char* str)
  94. {
  95. char* dup = strdup_impl(str);
  96. if (UNLIKELY(!dup)) {
  97. mozalloc_handle_oom(0);
  98. return moz_xstrdup(str);
  99. }
  100. return dup;
  101. }
  102. #if defined(HAVE_STRNDUP)
  103. char*
  104. moz_xstrndup(const char* str, size_t strsize)
  105. {
  106. char* dup = strndup_impl(str, strsize);
  107. if (UNLIKELY(!dup)) {
  108. mozalloc_handle_oom(strsize);
  109. return moz_xstrndup(str, strsize);
  110. }
  111. return dup;
  112. }
  113. #endif // if defined(HAVE_STRNDUP)
  114. #if defined(HAVE_POSIX_MEMALIGN)
  115. int
  116. moz_xposix_memalign(void **ptr, size_t alignment, size_t size)
  117. {
  118. int err = posix_memalign_impl(ptr, alignment, size);
  119. if (UNLIKELY(err && ENOMEM == err)) {
  120. mozalloc_handle_oom(size);
  121. return moz_xposix_memalign(ptr, alignment, size);
  122. }
  123. // else: (0 == err) or (EINVAL == err)
  124. return err;
  125. }
  126. int
  127. moz_posix_memalign(void **ptr, size_t alignment, size_t size)
  128. {
  129. int code = posix_memalign_impl(ptr, alignment, size);
  130. if (code)
  131. return code;
  132. return code;
  133. }
  134. #endif // if defined(HAVE_POSIX_MEMALIGN)
  135. #if defined(HAVE_MEMALIGN)
  136. void*
  137. moz_xmemalign(size_t boundary, size_t size)
  138. {
  139. void* ptr = memalign_impl(boundary, size);
  140. if (UNLIKELY(!ptr && EINVAL != errno)) {
  141. mozalloc_handle_oom(size);
  142. return moz_xmemalign(boundary, size);
  143. }
  144. // non-NULL ptr or errno == EINVAL
  145. return ptr;
  146. }
  147. #endif // if defined(HAVE_MEMALIGN)
  148. #if defined(HAVE_VALLOC)
  149. void*
  150. moz_xvalloc(size_t size)
  151. {
  152. void* ptr = valloc_impl(size);
  153. if (UNLIKELY(!ptr)) {
  154. mozalloc_handle_oom(size);
  155. return moz_xvalloc(size);
  156. }
  157. return ptr;
  158. }
  159. #endif // if defined(HAVE_VALLOC)
  160. #ifndef MOZ_STATIC_RUNTIME
  161. size_t
  162. moz_malloc_usable_size(void *ptr)
  163. {
  164. if (!ptr)
  165. return 0;
  166. #if defined(HAVE_MALLOC_USABLE_SIZE) || defined(MOZ_MEMORY)
  167. return malloc_usable_size_impl(ptr);
  168. #elif defined(XP_WIN)
  169. return _msize(ptr);
  170. #else
  171. return 0;
  172. #endif
  173. }
  174. size_t moz_malloc_size_of(const void *ptr)
  175. {
  176. return moz_malloc_usable_size((void *)ptr);
  177. }
  178. #endif