replace_malloc.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  3. * You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. #ifndef replace_malloc_h
  5. #define replace_malloc_h
  6. /*
  7. * The replace_malloc facility allows an external library to replace or
  8. * supplement the jemalloc implementation.
  9. *
  10. * The external library may be hooked by setting one of the following
  11. * environment variables to the library path:
  12. * - LD_PRELOAD on Linux,
  13. * - DYLD_INSERT_LIBRARIES on OSX,
  14. * - MOZ_REPLACE_MALLOC_LIB on Windows.
  15. *
  16. * An initialization function is called before any malloc replacement
  17. * function, and has the following declaration:
  18. *
  19. * void replace_init(const malloc_table_t *)
  20. *
  21. * The const malloc_table_t pointer given to that function is a table
  22. * containing pointers to the original jemalloc implementation, so that
  23. * replacement functions can call them back if they need to. The pointer
  24. * itself can safely be kept around (no need to copy the table itself).
  25. *
  26. * The functions to be implemented in the external library are of the form:
  27. *
  28. * void *replace_malloc(size_t size)
  29. * {
  30. * // Fiddle with the size if necessary.
  31. * // orig->malloc doesn't have to be called if the external library
  32. * // provides its own allocator, but in this case it will have to
  33. * // implement all functions.
  34. * void *ptr = orig->malloc(size);
  35. * // Do whatever you want with the ptr.
  36. * return ptr;
  37. * }
  38. *
  39. * where "orig" is the pointer obtained from replace_init.
  40. *
  41. * See malloc_decls.h for a list of functions that can be replaced this
  42. * way. The implementations are all in the form:
  43. * return_type replace_name(arguments [,...])
  44. *
  45. * They don't all need to be provided.
  46. *
  47. * Building a replace-malloc library is like rocket science. It can end up
  48. * with things blowing up, especially when trying to use complex types, and
  49. * even more especially when these types come from XPCOM or other parts of the
  50. * Mozilla codebase.
  51. * It is recommended to add the following to a replace-malloc implementation's
  52. * moz.build:
  53. * DISABLE_STL_WRAPPING = True # Avoid STL wrapping
  54. *
  55. * If your replace-malloc implementation lives under memory/replace, these
  56. * are taken care of by memory/replace/defs.mk.
  57. */
  58. #ifdef replace_malloc_bridge_h
  59. #error Do not include replace_malloc_bridge.h before replace_malloc.h. \
  60. In fact, you only need the latter.
  61. #endif
  62. #define REPLACE_MALLOC_IMPL
  63. #include "replace_malloc_bridge.h"
  64. /* Implementing a replace-malloc library is incompatible with using mozalloc. */
  65. #define MOZ_NO_MOZALLOC 1
  66. #include "mozilla/Types.h"
  67. MOZ_BEGIN_EXTERN_C
  68. /* MOZ_NO_REPLACE_FUNC_DECL and MOZ_REPLACE_WEAK are only defined in
  69. * replace_malloc.c. Normally including this header will add function
  70. * definitions. */
  71. #ifndef MOZ_NO_REPLACE_FUNC_DECL
  72. # ifndef MOZ_REPLACE_WEAK
  73. # define MOZ_REPLACE_WEAK
  74. # endif
  75. # define MALLOC_DECL(name, return_type, ...) \
  76. MOZ_EXPORT return_type replace_ ## name(__VA_ARGS__) MOZ_REPLACE_WEAK;
  77. # define MALLOC_FUNCS MALLOC_FUNCS_ALL
  78. # include "malloc_decls.h"
  79. #endif /* MOZ_NO_REPLACE_FUNC_DECL */
  80. /*
  81. * posix_memalign, aligned_alloc, memalign and valloc all implement some
  82. * kind of aligned memory allocation. For convenience, replace_posix_memalign,
  83. * replace_aligned_alloc and replace_valloc can be automatically derived from
  84. * memalign when MOZ_REPLACE_ONLY_MEMALIGN is defined before including this
  85. * header. PAGE_SIZE also needs to be defined to the appropriate expression.
  86. */
  87. #ifdef MOZ_REPLACE_ONLY_MEMALIGN
  88. #include <errno.h>
  89. int replace_posix_memalign(void **ptr, size_t alignment, size_t size)
  90. {
  91. if (size == 0) {
  92. *ptr = NULL;
  93. return 0;
  94. }
  95. /* alignment must be a power of two and a multiple of sizeof(void *) */
  96. if (((alignment - 1) & alignment) != 0 || (alignment % sizeof(void *)))
  97. return EINVAL;
  98. *ptr = replace_memalign(alignment, size);
  99. return *ptr ? 0 : ENOMEM;
  100. }
  101. void *replace_aligned_alloc(size_t alignment, size_t size)
  102. {
  103. /* size should be a multiple of alignment */
  104. if (size % alignment)
  105. return NULL;
  106. return replace_memalign(alignment, size);
  107. }
  108. void *replace_valloc(size_t size)
  109. {
  110. return replace_memalign(PAGE_SIZE, size);
  111. }
  112. #endif
  113. MOZ_END_EXTERN_C
  114. #endif /* replace_malloc_h */