jsalloc.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  2. * vim: set ts=8 sts=4 et sw=4 tw=99:
  3. * This Source Code Form is subject to the terms of the Mozilla Public
  4. * License, v. 2.0. If a copy of the MPL was not distributed with this
  5. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6. /*
  7. * JS allocation policies.
  8. *
  9. * The allocators here are for system memory with lifetimes which are not
  10. * managed by the GC. See the comment at the top of vm/MallocProvider.h.
  11. */
  12. #ifndef jsalloc_h
  13. #define jsalloc_h
  14. #include "js/TypeDecls.h"
  15. #include "js/Utility.h"
  16. namespace js {
  17. enum class AllocFunction {
  18. Malloc,
  19. Calloc,
  20. Realloc
  21. };
  22. struct ContextFriendFields;
  23. /* Policy for using system memory functions and doing no error reporting. */
  24. class SystemAllocPolicy
  25. {
  26. public:
  27. template <typename T> T* maybe_pod_malloc(size_t numElems) { return js_pod_malloc<T>(numElems); }
  28. template <typename T> T* maybe_pod_calloc(size_t numElems) { return js_pod_calloc<T>(numElems); }
  29. template <typename T> T* maybe_pod_realloc(T* p, size_t oldSize, size_t newSize) {
  30. return js_pod_realloc<T>(p, oldSize, newSize);
  31. }
  32. template <typename T> T* pod_malloc(size_t numElems) { return maybe_pod_malloc<T>(numElems); }
  33. template <typename T> T* pod_calloc(size_t numElems) { return maybe_pod_calloc<T>(numElems); }
  34. template <typename T> T* pod_realloc(T* p, size_t oldSize, size_t newSize) {
  35. return maybe_pod_realloc<T>(p, oldSize, newSize);
  36. }
  37. void free_(void* p) { js_free(p); }
  38. void reportAllocOverflow() const {}
  39. bool checkSimulatedOOM() const {
  40. return !js::oom::ShouldFailWithOOM();
  41. }
  42. };
  43. class ExclusiveContext;
  44. void ReportOutOfMemory(ExclusiveContext* cxArg);
  45. /*
  46. * Allocation policy that calls the system memory functions and reports errors
  47. * to the context. Since the JSContext given on construction is stored for
  48. * the lifetime of the container, this policy may only be used for containers
  49. * whose lifetime is a shorter than the given JSContext.
  50. *
  51. * FIXME bug 647103 - rewrite this in terms of temporary allocation functions,
  52. * not the system ones.
  53. */
  54. class TempAllocPolicy
  55. {
  56. ContextFriendFields* const cx_;
  57. /*
  58. * Non-inline helper to call JSRuntime::onOutOfMemory with minimal
  59. * code bloat.
  60. */
  61. JS_FRIEND_API(void*) onOutOfMemory(AllocFunction allocFunc, size_t nbytes,
  62. void* reallocPtr = nullptr);
  63. template <typename T>
  64. T* onOutOfMemoryTyped(AllocFunction allocFunc, size_t numElems, void* reallocPtr = nullptr) {
  65. size_t bytes;
  66. if (MOZ_UNLIKELY(!CalculateAllocSize<T>(numElems, &bytes)))
  67. return nullptr;
  68. return static_cast<T*>(onOutOfMemory(allocFunc, bytes, reallocPtr));
  69. }
  70. public:
  71. MOZ_IMPLICIT TempAllocPolicy(JSContext* cx) : cx_((ContextFriendFields*) cx) {} // :(
  72. MOZ_IMPLICIT TempAllocPolicy(ContextFriendFields* cx) : cx_(cx) {}
  73. template <typename T>
  74. T* maybe_pod_malloc(size_t numElems) {
  75. return js_pod_malloc<T>(numElems);
  76. }
  77. template <typename T>
  78. T* maybe_pod_calloc(size_t numElems) {
  79. return js_pod_calloc<T>(numElems);
  80. }
  81. template <typename T>
  82. T* maybe_pod_realloc(T* prior, size_t oldSize, size_t newSize) {
  83. return js_pod_realloc<T>(prior, oldSize, newSize);
  84. }
  85. template <typename T>
  86. T* pod_malloc(size_t numElems) {
  87. T* p = maybe_pod_malloc<T>(numElems);
  88. if (MOZ_UNLIKELY(!p))
  89. p = onOutOfMemoryTyped<T>(AllocFunction::Malloc, numElems);
  90. return p;
  91. }
  92. template <typename T>
  93. T* pod_calloc(size_t numElems) {
  94. T* p = maybe_pod_calloc<T>(numElems);
  95. if (MOZ_UNLIKELY(!p))
  96. p = onOutOfMemoryTyped<T>(AllocFunction::Calloc, numElems);
  97. return p;
  98. }
  99. template <typename T>
  100. T* pod_realloc(T* prior, size_t oldSize, size_t newSize) {
  101. T* p2 = maybe_pod_realloc<T>(prior, oldSize, newSize);
  102. if (MOZ_UNLIKELY(!p2))
  103. p2 = onOutOfMemoryTyped<T>(AllocFunction::Realloc, newSize, prior);
  104. return p2;
  105. }
  106. void free_(void* p) {
  107. js_free(p);
  108. }
  109. JS_FRIEND_API(void) reportAllocOverflow() const;
  110. bool checkSimulatedOOM() const {
  111. if (js::oom::ShouldFailWithOOM()) {
  112. js::ReportOutOfMemory(reinterpret_cast<ExclusiveContext*>(cx_));
  113. return false;
  114. }
  115. return true;
  116. }
  117. };
  118. } /* namespace js */
  119. #endif /* jsalloc_h */