gecko-dev/js/public/AllocPolicy.h
Andreea Pavel 840f785b1e Backed out 8 changesets (bug 1475228) for wpt failures e.g. html/semantics/scripting-1/the-script-element/execution-timing/088.html on a CLOSED TREE
Backed out changeset b2d18ea619ec (bug 1475228)
Backed out changeset 45d3ffe3308e (bug 1475228)
Backed out changeset 02b27f8441be (bug 1475228)
Backed out changeset b82c2cf4b3f1 (bug 1475228)
Backed out changeset 2bc8f24dc3fc (bug 1475228)
Backed out changeset 6104ea971587 (bug 1475228)
Backed out changeset 7c83633262db (bug 1475228)
Backed out changeset 34fb24d52f08 (bug 1475228)
2018-07-30 16:49:02 +03:00

176 lines
5.7 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* JS allocation policies.
*
* The allocators here are for system memory with lifetimes which are not
* managed by the GC. See the comment at the top of vm/MallocProvider.h.
*/
#ifndef js_AllocPolicy_h
#define js_AllocPolicy_h
#include "js/TypeDecls.h"
#include "js/Utility.h"
extern MOZ_COLD JS_PUBLIC_API(void) JS_ReportOutOfMemory(JSContext* cx);
namespace js {
enum class AllocFunction {
Malloc,
Calloc,
Realloc
};
/* Policy for using system memory functions and doing no error reporting. */
class SystemAllocPolicy
{
public:
template <typename T> T* maybe_pod_malloc(size_t numElems) { return js_pod_malloc<T>(numElems); }
template <typename T> T* maybe_pod_calloc(size_t numElems) { return js_pod_calloc<T>(numElems); }
template <typename T> T* maybe_pod_realloc(T* p, size_t oldSize, size_t newSize) {
return js_pod_realloc<T>(p, oldSize, newSize);
}
template <typename T> T* pod_malloc(size_t numElems) { return maybe_pod_malloc<T>(numElems); }
template <typename T> T* pod_calloc(size_t numElems) { return maybe_pod_calloc<T>(numElems); }
template <typename T> T* pod_realloc(T* p, size_t oldSize, size_t newSize) {
return maybe_pod_realloc<T>(p, oldSize, newSize);
}
template <typename T> void free_(T* p, size_t numElems = 0) { js_free(p); }
void reportAllocOverflow() const {}
bool checkSimulatedOOM() const {
return !js::oom::ShouldFailWithOOM();
}
};
MOZ_COLD JS_FRIEND_API(void) ReportOutOfMemory(JSContext* cx);
/*
* Allocation policy that calls the system memory functions and reports errors
* to the context. Since the JSContext given on construction is stored for
* the lifetime of the container, this policy may only be used for containers
* whose lifetime is a shorter than the given JSContext.
*
* FIXME bug 647103 - rewrite this in terms of temporary allocation functions,
* not the system ones.
*/
class TempAllocPolicy
{
JSContext* const cx_;
/*
* Non-inline helper to call JSRuntime::onOutOfMemory with minimal
* code bloat.
*/
JS_FRIEND_API(void*) onOutOfMemory(AllocFunction allocFunc, size_t nbytes,
void* reallocPtr = nullptr);
template <typename T>
T* onOutOfMemoryTyped(AllocFunction allocFunc, size_t numElems, void* reallocPtr = nullptr) {
size_t bytes;
if (MOZ_UNLIKELY(!CalculateAllocSize<T>(numElems, &bytes)))
return nullptr;
return static_cast<T*>(onOutOfMemory(allocFunc, bytes, reallocPtr));
}
public:
MOZ_IMPLICIT TempAllocPolicy(JSContext* cx) : cx_(cx) {}
template <typename T>
T* maybe_pod_malloc(size_t numElems) {
return js_pod_malloc<T>(numElems);
}
template <typename T>
T* maybe_pod_calloc(size_t numElems) {
return js_pod_calloc<T>(numElems);
}
template <typename T>
T* maybe_pod_realloc(T* prior, size_t oldSize, size_t newSize) {
return js_pod_realloc<T>(prior, oldSize, newSize);
}
template <typename T>
T* pod_malloc(size_t numElems) {
T* p = maybe_pod_malloc<T>(numElems);
if (MOZ_UNLIKELY(!p))
p = onOutOfMemoryTyped<T>(AllocFunction::Malloc, numElems);
return p;
}
template <typename T>
T* pod_calloc(size_t numElems) {
T* p = maybe_pod_calloc<T>(numElems);
if (MOZ_UNLIKELY(!p))
p = onOutOfMemoryTyped<T>(AllocFunction::Calloc, numElems);
return p;
}
template <typename T>
T* pod_realloc(T* prior, size_t oldSize, size_t newSize) {
T* p2 = maybe_pod_realloc<T>(prior, oldSize, newSize);
if (MOZ_UNLIKELY(!p2))
p2 = onOutOfMemoryTyped<T>(AllocFunction::Realloc, newSize, prior);
return p2;
}
template <typename T>
void free_(T* p, size_t numElems = 0) {
js_free(p);
}
JS_FRIEND_API(void) reportAllocOverflow() const;
bool checkSimulatedOOM() const {
if (js::oom::ShouldFailWithOOM()) {
ReportOutOfMemory(cx_);
return false;
}
return true;
}
};
/*
* Allocation policy that uses Zone::pod_malloc and friends, so that memory
* pressure is accounted for on the zone. This is suitable for memory associated
* with GC things allocated in the zone.
*
* Since it doesn't hold a JSContext (those may not live long enough), it can't
* report out-of-memory conditions itself; the caller must check for OOM and
* take the appropriate action.
*
* FIXME bug 647103 - replace these *AllocPolicy names.
*/
class ZoneAllocPolicy
{
JS::Zone* const zone;
public:
MOZ_IMPLICIT ZoneAllocPolicy(JS::Zone* z) : zone(z) {}
// These methods are defined in gc/Zone.h.
template <typename T> inline T* maybe_pod_malloc(size_t numElems);
template <typename T> inline T* maybe_pod_calloc(size_t numElems);
template <typename T> inline T* maybe_pod_realloc(T* p, size_t oldSize, size_t newSize);
template <typename T> inline T* pod_malloc(size_t numElems);
template <typename T> inline T* pod_calloc(size_t numElems);
template <typename T> inline T* pod_realloc(T* p, size_t oldSize, size_t newSize);
template <typename T> void free_(T* p, size_t numElems = 0) { js_free(p); }
void reportAllocOverflow() const {}
MOZ_MUST_USE bool checkSimulatedOOM() const {
return !js::oom::ShouldFailWithOOM();
}
};
} /* namespace js */
#endif /* js_AllocPolicy_h */