Bug 1690340 - Part 4: Insert the "Page Source" before the "Extensions for Developers...
[gecko.git] / js / public / AllocPolicy.h
blobbf15889bfc4777c0b7e52fd6d14caabb660fa6ac
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
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/. */
7 /*
8 * JS allocation policies.
10 * The allocators here are for system memory with lifetimes which are not
11 * managed by the GC. See the comment at the top of vm/MallocProvider.h.
14 #ifndef js_AllocPolicy_h
15 #define js_AllocPolicy_h
17 #include "js/TypeDecls.h"
18 #include "js/Utility.h"
20 extern MOZ_COLD JS_PUBLIC_API void JS_ReportOutOfMemory(JSContext* cx);
22 namespace js {
24 enum class AllocFunction { Malloc, Calloc, Realloc };
26 /* Base class allocation policies providing allocation methods. */
27 class AllocPolicyBase {
28 public:
29 template <typename T>
30 T* maybe_pod_arena_malloc(arena_id_t arenaId, size_t numElems) {
31 return js_pod_arena_malloc<T>(arenaId, numElems);
33 template <typename T>
34 T* maybe_pod_arena_calloc(arena_id_t arenaId, size_t numElems) {
35 return js_pod_arena_calloc<T>(arenaId, numElems);
37 template <typename T>
38 T* maybe_pod_arena_realloc(arena_id_t arenaId, T* p, size_t oldSize,
39 size_t newSize) {
40 return js_pod_arena_realloc<T>(arenaId, p, oldSize, newSize);
42 template <typename T>
43 T* pod_arena_malloc(arena_id_t arenaId, size_t numElems) {
44 return maybe_pod_arena_malloc<T>(arenaId, numElems);
46 template <typename T>
47 T* pod_arena_calloc(arena_id_t arenaId, size_t numElems) {
48 return maybe_pod_arena_calloc<T>(arenaId, numElems);
50 template <typename T>
51 T* pod_arena_realloc(arena_id_t arenaId, T* p, size_t oldSize,
52 size_t newSize) {
53 return maybe_pod_arena_realloc<T>(arenaId, p, oldSize, newSize);
56 template <typename T>
57 T* maybe_pod_malloc(size_t numElems) {
58 return maybe_pod_arena_malloc<T>(js::MallocArena, numElems);
60 template <typename T>
61 T* maybe_pod_calloc(size_t numElems) {
62 return maybe_pod_arena_calloc<T>(js::MallocArena, numElems);
64 template <typename T>
65 T* maybe_pod_realloc(T* p, size_t oldSize, size_t newSize) {
66 return maybe_pod_arena_realloc<T>(js::MallocArena, p, oldSize, newSize);
68 template <typename T>
69 T* pod_malloc(size_t numElems) {
70 return pod_arena_malloc<T>(js::MallocArena, numElems);
72 template <typename T>
73 T* pod_calloc(size_t numElems) {
74 return pod_arena_calloc<T>(js::MallocArena, numElems);
76 template <typename T>
77 T* pod_realloc(T* p, size_t oldSize, size_t newSize) {
78 return pod_arena_realloc<T>(js::MallocArena, p, oldSize, newSize);
81 template <typename T>
82 void free_(T* p, size_t numElems = 0) {
83 js_free(p);
87 /* Policy for using system memory functions and doing no error reporting. */
88 class SystemAllocPolicy : public AllocPolicyBase {
89 public:
90 void reportAllocOverflow() const {}
91 bool checkSimulatedOOM() const { return !js::oom::ShouldFailWithOOM(); }
94 MOZ_COLD JS_FRIEND_API void ReportOutOfMemory(JSContext* cx);
97 * Allocation policy that calls the system memory functions and reports errors
98 * to the context. Since the JSContext given on construction is stored for
99 * the lifetime of the container, this policy may only be used for containers
100 * whose lifetime is a shorter than the given JSContext.
102 * FIXME bug 647103 - rewrite this in terms of temporary allocation functions,
103 * not the system ones.
105 class TempAllocPolicy : public AllocPolicyBase {
106 JSContext* const cx_;
109 * Non-inline helper to call JSRuntime::onOutOfMemory with minimal
110 * code bloat.
112 JS_FRIEND_API void* onOutOfMemory(arena_id_t arenaId, AllocFunction allocFunc,
113 size_t nbytes, void* reallocPtr = nullptr);
115 template <typename T>
116 T* onOutOfMemoryTyped(arena_id_t arenaId, AllocFunction allocFunc,
117 size_t numElems, void* reallocPtr = nullptr) {
118 size_t bytes;
119 if (MOZ_UNLIKELY(!CalculateAllocSize<T>(numElems, &bytes))) {
120 return nullptr;
122 return static_cast<T*>(
123 onOutOfMemory(arenaId, allocFunc, bytes, reallocPtr));
126 public:
127 MOZ_IMPLICIT TempAllocPolicy(JSContext* cx) : cx_(cx) {}
129 template <typename T>
130 T* pod_arena_malloc(arena_id_t arenaId, size_t numElems) {
131 T* p = this->maybe_pod_arena_malloc<T>(arenaId, numElems);
132 if (MOZ_UNLIKELY(!p)) {
133 p = onOutOfMemoryTyped<T>(arenaId, AllocFunction::Malloc, numElems);
135 return p;
138 template <typename T>
139 T* pod_arena_calloc(arena_id_t arenaId, size_t numElems) {
140 T* p = this->maybe_pod_arena_calloc<T>(arenaId, numElems);
141 if (MOZ_UNLIKELY(!p)) {
142 p = onOutOfMemoryTyped<T>(arenaId, AllocFunction::Calloc, numElems);
144 return p;
147 template <typename T>
148 T* pod_arena_realloc(arena_id_t arenaId, T* prior, size_t oldSize,
149 size_t newSize) {
150 T* p2 = this->maybe_pod_arena_realloc<T>(arenaId, prior, oldSize, newSize);
151 if (MOZ_UNLIKELY(!p2)) {
152 p2 = onOutOfMemoryTyped<T>(arenaId, AllocFunction::Realloc, newSize,
153 prior);
155 return p2;
158 template <typename T>
159 T* pod_malloc(size_t numElems) {
160 return pod_arena_malloc<T>(js::MallocArena, numElems);
163 template <typename T>
164 T* pod_calloc(size_t numElems) {
165 return pod_arena_calloc<T>(js::MallocArena, numElems);
168 template <typename T>
169 T* pod_realloc(T* prior, size_t oldSize, size_t newSize) {
170 return pod_arena_realloc<T>(js::MallocArena, prior, oldSize, newSize);
173 template <typename T>
174 void free_(T* p, size_t numElems = 0) {
175 js_free(p);
178 JS_FRIEND_API void reportAllocOverflow() const;
180 bool checkSimulatedOOM() const {
181 if (js::oom::ShouldFailWithOOM()) {
182 ReportOutOfMemory(cx_);
183 return false;
186 return true;
191 * A replacement for MallocAllocPolicy that allocates in the JS heap and adds no
192 * extra behaviours.
194 * This is currently used for allocating source buffers for parsing. Since these
195 * are temporary and will not be freed by GC, the memory is not tracked by the
196 * usual accounting.
198 class MallocAllocPolicy : public AllocPolicyBase {
199 public:
200 void reportAllocOverflow() const {}
202 [[nodiscard]] bool checkSimulatedOOM() const { return true; }
205 } /* namespace js */
207 #endif /* js_AllocPolicy_h */