mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1208665 r=Waldo a=abillings
This commit is contained in:
parent
31464b93bf
commit
238a6a97b2
@ -336,6 +336,36 @@ static inline char* js_strdup(const char* s)
|
||||
|
||||
JS_DECLARE_NEW_METHODS(js_new, js_malloc, static MOZ_ALWAYS_INLINE)
|
||||
|
||||
namespace js {
|
||||
|
||||
/*
|
||||
* Calculate the number of bytes needed to allocate |numElems| contiguous
|
||||
* instances of type |T|. Return false if the calculation overflowed.
|
||||
*/
|
||||
template <typename T>
|
||||
MOZ_WARN_UNUSED_RESULT inline bool
|
||||
CalculateAllocSize(size_t numElems, size_t* bytesOut)
|
||||
{
|
||||
*bytesOut = numElems * sizeof(T);
|
||||
return (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value) == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the number of bytes needed to allocate a single instance of type
|
||||
* |T| followed by |numExtra| contiguous instances of type |Extra|. Return
|
||||
* false if the calculation overflowed.
|
||||
*/
|
||||
template <typename T, typename Extra>
|
||||
MOZ_WARN_UNUSED_RESULT inline bool
|
||||
CalculateAllocSizeWithExtra(size_t numExtra, size_t* bytesOut)
|
||||
{
|
||||
*bytesOut = sizeof(T) + numExtra * sizeof(Extra);
|
||||
return (numExtra & mozilla::tl::MulOverflowMask<sizeof(Extra)>::value) == 0 &&
|
||||
*bytesOut >= sizeof(T);
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
template <class T>
|
||||
static MOZ_ALWAYS_INLINE void
|
||||
js_delete(const T* p)
|
||||
@ -361,32 +391,34 @@ template <class T>
|
||||
static MOZ_ALWAYS_INLINE T*
|
||||
js_pod_malloc()
|
||||
{
|
||||
return (T*)js_malloc(sizeof(T));
|
||||
return static_cast<T*>(js_malloc(sizeof(T)));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static MOZ_ALWAYS_INLINE T*
|
||||
js_pod_calloc()
|
||||
{
|
||||
return (T*)js_calloc(sizeof(T));
|
||||
return static_cast<T*>(js_calloc(sizeof(T)));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static MOZ_ALWAYS_INLINE T*
|
||||
js_pod_malloc(size_t numElems)
|
||||
{
|
||||
if (MOZ_UNLIKELY(numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value))
|
||||
size_t bytes;
|
||||
if (MOZ_UNLIKELY(!js::CalculateAllocSize<T>(numElems, &bytes)))
|
||||
return nullptr;
|
||||
return (T*)js_malloc(numElems * sizeof(T));
|
||||
return static_cast<T*>(js_malloc(bytes));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static MOZ_ALWAYS_INLINE T*
|
||||
js_pod_calloc(size_t numElems)
|
||||
{
|
||||
if (MOZ_UNLIKELY(numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value))
|
||||
size_t bytes;
|
||||
if (MOZ_UNLIKELY(!js::CalculateAllocSize<T>(numElems, &bytes)))
|
||||
return nullptr;
|
||||
return (T*)js_calloc(numElems * sizeof(T));
|
||||
return static_cast<T*>(js_calloc(bytes));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
@ -394,9 +426,10 @@ static MOZ_ALWAYS_INLINE T*
|
||||
js_pod_realloc(T* prior, size_t oldSize, size_t newSize)
|
||||
{
|
||||
MOZ_ASSERT(!(oldSize & mozilla::tl::MulOverflowMask<sizeof(T)>::value));
|
||||
if (MOZ_UNLIKELY(newSize & mozilla::tl::MulOverflowMask<sizeof(T)>::value))
|
||||
size_t bytes;
|
||||
if (MOZ_UNLIKELY(!js::CalculateAllocSize<T>(newSize, &bytes)))
|
||||
return nullptr;
|
||||
return (T*)js_realloc(prior, newSize * sizeof(T));
|
||||
return static_cast<T*>(js_realloc(prior, bytes));
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
@ -315,9 +315,10 @@ class LifoAlloc
|
||||
// The caller is responsible for initialization.
|
||||
template <typename T>
|
||||
T* newArrayUninitialized(size_t count) {
|
||||
if (MOZ_UNLIKELY(count & mozilla::tl::MulOverflowMask<sizeof(T)>::value))
|
||||
size_t bytes;
|
||||
if (MOZ_UNLIKELY(!CalculateAllocSize<T>(count, &bytes)))
|
||||
return nullptr;
|
||||
return static_cast<T*>(alloc(sizeof(T) * count));
|
||||
return static_cast<T*>(alloc(bytes));
|
||||
}
|
||||
|
||||
class Mark {
|
||||
@ -532,24 +533,24 @@ class LifoAllocPolicy
|
||||
{}
|
||||
template <typename T>
|
||||
T* maybe_pod_malloc(size_t numElems) {
|
||||
if (MOZ_UNLIKELY(numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value))
|
||||
size_t bytes;
|
||||
if (MOZ_UNLIKELY(!CalculateAllocSize<T>(numElems, &bytes)))
|
||||
return nullptr;
|
||||
size_t bytes = numElems * sizeof(T);
|
||||
void* p = fb == Fallible ? alloc_.alloc(bytes) : alloc_.allocInfallible(bytes);
|
||||
return static_cast<T*>(p);
|
||||
}
|
||||
template <typename T>
|
||||
T* maybe_pod_calloc(size_t numElems) {
|
||||
T* p = pod_malloc<T>(numElems);
|
||||
if (fb == Fallible && !p)
|
||||
T* p = maybe_pod_malloc<T>(numElems);
|
||||
if (MOZ_UNLIKELY(!p))
|
||||
return nullptr;
|
||||
memset(p, 0, numElems * sizeof(T));
|
||||
return p;
|
||||
}
|
||||
template <typename T>
|
||||
T* maybe_pod_realloc(T* p, size_t oldSize, size_t newSize) {
|
||||
T* n = pod_malloc<T>(newSize);
|
||||
if (fb == Fallible && !n)
|
||||
T* n = maybe_pod_malloc<T>(newSize);
|
||||
if (MOZ_UNLIKELY(!n))
|
||||
return nullptr;
|
||||
MOZ_ASSERT(!(oldSize & mozilla::tl::MulOverflowMask<sizeof(T)>::value));
|
||||
memcpy(n, p, Min(oldSize * sizeof(T), newSize * sizeof(T)));
|
||||
|
@ -37,9 +37,10 @@ class FixedList
|
||||
if (length == 0)
|
||||
return true;
|
||||
|
||||
if (MOZ_UNLIKELY(length & mozilla::tl::MulOverflowMask<sizeof(T)>::value))
|
||||
size_t bytes;
|
||||
if (MOZ_UNLIKELY(!CalculateAllocSize<T>(length, &bytes)))
|
||||
return false;
|
||||
list_ = (T*)alloc.allocate(length * sizeof(T));
|
||||
list_ = (T*)alloc.allocate(bytes);
|
||||
return list_ != nullptr;
|
||||
}
|
||||
|
||||
@ -60,9 +61,10 @@ class FixedList
|
||||
size_t newlength = length_ + num;
|
||||
if (newlength < length_)
|
||||
return false;
|
||||
if (MOZ_UNLIKELY(newlength & mozilla::tl::MulOverflowMask<sizeof(T)>::value))
|
||||
size_t bytes;
|
||||
if (MOZ_UNLIKELY(!CalculateAllocSize<T>(newlength, &bytes)))
|
||||
return false;
|
||||
T* list = (T*)alloc.allocate((length_ + num) * sizeof(T));
|
||||
T* list = (T*)alloc.allocate(bytes);
|
||||
if (MOZ_UNLIKELY(!list))
|
||||
return false;
|
||||
|
||||
|
@ -48,12 +48,13 @@ class TempAllocator
|
||||
return p;
|
||||
}
|
||||
|
||||
template <size_t ElemSize>
|
||||
void* allocateArray(size_t n)
|
||||
template <typename T>
|
||||
T* allocateArray(size_t n)
|
||||
{
|
||||
if (MOZ_UNLIKELY(n & mozilla::tl::MulOverflowMask<ElemSize>::value))
|
||||
size_t bytes;
|
||||
if (MOZ_UNLIKELY(!CalculateAllocSize<T>(n, &bytes)))
|
||||
return nullptr;
|
||||
void* p = lifoScope_.alloc().alloc(n * ElemSize);
|
||||
T* p = static_cast<T*>(lifoScope_.alloc().alloc(bytes));
|
||||
if (MOZ_UNLIKELY(!ensureBallast()))
|
||||
return nullptr;
|
||||
return p;
|
||||
@ -79,13 +80,14 @@ class JitAllocPolicy
|
||||
{}
|
||||
template <typename T>
|
||||
T* maybe_pod_malloc(size_t numElems) {
|
||||
if (MOZ_UNLIKELY(numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value))
|
||||
size_t bytes;
|
||||
if (MOZ_UNLIKELY(!CalculateAllocSize<T>(numElems, &bytes)))
|
||||
return nullptr;
|
||||
return static_cast<T*>(alloc_.allocate(numElems * sizeof(T)));
|
||||
return static_cast<T*>(alloc_.allocate(bytes));
|
||||
}
|
||||
template <typename T>
|
||||
T* maybe_pod_calloc(size_t numElems) {
|
||||
T* p = pod_malloc<T>(numElems);
|
||||
T* p = maybe_pod_malloc<T>(numElems);
|
||||
if (MOZ_LIKELY(p))
|
||||
memset(p, 0, numElems * sizeof(T));
|
||||
return p;
|
||||
@ -127,9 +129,10 @@ class OldJitAllocPolicy
|
||||
{}
|
||||
template <typename T>
|
||||
T* maybe_pod_malloc(size_t numElems) {
|
||||
if (MOZ_UNLIKELY(numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value))
|
||||
size_t bytes;
|
||||
if (MOZ_UNLIKELY(!CalculateAllocSize<T>(numElems, &bytes)))
|
||||
return nullptr;
|
||||
return static_cast<T*>(GetJitContext()->temp->allocate(numElems * sizeof(T)));
|
||||
return static_cast<T*>(GetJitContext()->temp->allocate(bytes));
|
||||
}
|
||||
template <typename T>
|
||||
T* pod_malloc(size_t numElems) {
|
||||
|
@ -107,8 +107,7 @@ LBlock::init(TempAllocator& alloc)
|
||||
|
||||
int numPhis = (phi->type() == MIRType_Value) ? BOX_PIECES : 1;
|
||||
for (int i = 0; i < numPhis; i++) {
|
||||
void* array = alloc.allocateArray<sizeof(LAllocation)>(numPreds);
|
||||
LAllocation* inputs = static_cast<LAllocation*>(array);
|
||||
LAllocation* inputs = alloc.allocateArray<LAllocation>(numPreds);
|
||||
if (!inputs)
|
||||
return false;
|
||||
|
||||
|
@ -62,10 +62,11 @@ class MIRGenerator
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T * allocate(size_t count = 1) {
|
||||
if (count & mozilla::tl::MulOverflowMask<sizeof(T)>::value)
|
||||
T* allocate(size_t count = 1) {
|
||||
size_t bytes;
|
||||
if (MOZ_UNLIKELY(!CalculateAllocSize<T>(count, &bytes)))
|
||||
return nullptr;
|
||||
return reinterpret_cast<T*>(alloc().allocate(sizeof(T) * count));
|
||||
return static_cast<T*>(alloc().allocate(bytes));
|
||||
}
|
||||
|
||||
// Set an error state and prints a message. Returns false so errors can be
|
||||
|
@ -346,7 +346,7 @@ MBasicBlock::NewAsmJS(MIRGraph& graph, CompileInfo& info, MBasicBlock* pred, Kin
|
||||
size_t nphis = block->stackPosition_;
|
||||
|
||||
TempAllocator& alloc = graph.alloc();
|
||||
MPhi* phis = (MPhi*)alloc.allocateArray<sizeof(MPhi)>(nphis);
|
||||
MPhi* phis = alloc.allocateArray<MPhi>(nphis);
|
||||
if (!phis)
|
||||
return nullptr;
|
||||
|
||||
|
@ -71,6 +71,14 @@ class TempAllocPolicy
|
||||
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_((ContextFriendFields*) cx) {} // :(
|
||||
MOZ_IMPLICIT TempAllocPolicy(ContextFriendFields* cx) : cx_(cx) {}
|
||||
@ -94,7 +102,7 @@ class TempAllocPolicy
|
||||
T* pod_malloc(size_t numElems) {
|
||||
T* p = maybe_pod_malloc<T>(numElems);
|
||||
if (MOZ_UNLIKELY(!p))
|
||||
p = static_cast<T*>(onOutOfMemory(AllocFunction::Malloc, numElems * sizeof(T)));
|
||||
p = onOutOfMemoryTyped<T>(AllocFunction::Malloc, numElems);
|
||||
return p;
|
||||
}
|
||||
|
||||
@ -102,7 +110,7 @@ class TempAllocPolicy
|
||||
T* pod_calloc(size_t numElems) {
|
||||
T* p = maybe_pod_calloc<T>(numElems);
|
||||
if (MOZ_UNLIKELY(!p))
|
||||
p = static_cast<T*>(onOutOfMemory(AllocFunction::Calloc, numElems * sizeof(T)));
|
||||
p = onOutOfMemoryTyped<T>(AllocFunction::Calloc, numElems);
|
||||
return p;
|
||||
}
|
||||
|
||||
@ -110,7 +118,7 @@ class TempAllocPolicy
|
||||
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 = static_cast<T*>(onOutOfMemory(AllocFunction::Realloc, newSize * sizeof(T), prior));
|
||||
p2 = onOutOfMemoryTyped<T>(AllocFunction::Realloc, newSize, prior);
|
||||
return p2;
|
||||
}
|
||||
|
||||
|
@ -52,19 +52,17 @@ struct MallocProvider
|
||||
{
|
||||
template <class T>
|
||||
T* maybe_pod_malloc(size_t numElems) {
|
||||
size_t bytes = numElems * sizeof(T);
|
||||
T* p = js_pod_malloc<T>(numElems);
|
||||
if (MOZ_LIKELY(p))
|
||||
client()->updateMallocCounter(bytes);
|
||||
client()->updateMallocCounter(numElems * sizeof(T));
|
||||
return p;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T* maybe_pod_calloc(size_t numElems) {
|
||||
size_t bytes = numElems * sizeof(T);
|
||||
T* p = js_pod_calloc<T>(numElems);
|
||||
if (MOZ_LIKELY(p))
|
||||
client()->updateMallocCounter(bytes);
|
||||
client()->updateMallocCounter(numElems * sizeof(T));
|
||||
return p;
|
||||
}
|
||||
|
||||
@ -90,11 +88,11 @@ struct MallocProvider
|
||||
T* p = maybe_pod_malloc<T>(numElems);
|
||||
if (MOZ_LIKELY(p))
|
||||
return p;
|
||||
if (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value) {
|
||||
size_t bytes;
|
||||
if (MOZ_UNLIKELY(!CalculateAllocSize<T>(numElems, &bytes))) {
|
||||
client()->reportAllocationOverflow();
|
||||
return nullptr;
|
||||
}
|
||||
size_t bytes = numElems * sizeof(T);
|
||||
p = (T*)client()->onOutOfMemory(AllocFunction::Malloc, bytes);
|
||||
if (p)
|
||||
client()->updateMallocCounter(bytes);
|
||||
@ -103,16 +101,12 @@ struct MallocProvider
|
||||
|
||||
template <class T, class U>
|
||||
T* pod_malloc_with_extra(size_t numExtra) {
|
||||
if (MOZ_UNLIKELY(numExtra & mozilla::tl::MulOverflowMask<sizeof(U)>::value)) {
|
||||
size_t bytes;
|
||||
if (MOZ_UNLIKELY((!CalculateAllocSizeWithExtra<T, U>(numExtra, &bytes)))) {
|
||||
client()->reportAllocationOverflow();
|
||||
return nullptr;
|
||||
}
|
||||
size_t bytes = sizeof(T) + numExtra * sizeof(U);
|
||||
if (MOZ_UNLIKELY(bytes < sizeof(T))) {
|
||||
client()->reportAllocationOverflow();
|
||||
return nullptr;
|
||||
}
|
||||
T* p = reinterpret_cast<T*>(js_pod_malloc<uint8_t>(bytes));
|
||||
T* p = static_cast<T*>(js_malloc(bytes));
|
||||
if (MOZ_LIKELY(p)) {
|
||||
client()->updateMallocCounter(bytes);
|
||||
return p;
|
||||
@ -139,11 +133,11 @@ struct MallocProvider
|
||||
T* p = maybe_pod_calloc<T>(numElems);
|
||||
if (MOZ_LIKELY(p))
|
||||
return p;
|
||||
if (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value) {
|
||||
size_t bytes;
|
||||
if (MOZ_UNLIKELY(!CalculateAllocSize<T>(numElems, &bytes))) {
|
||||
client()->reportAllocationOverflow();
|
||||
return nullptr;
|
||||
}
|
||||
size_t bytes = numElems * sizeof(T);
|
||||
p = (T*)client()->onOutOfMemory(AllocFunction::Calloc, bytes);
|
||||
if (p)
|
||||
client()->updateMallocCounter(bytes);
|
||||
@ -152,16 +146,12 @@ struct MallocProvider
|
||||
|
||||
template <class T, class U>
|
||||
T* pod_calloc_with_extra(size_t numExtra) {
|
||||
if (MOZ_UNLIKELY(numExtra & mozilla::tl::MulOverflowMask<sizeof(U)>::value)) {
|
||||
size_t bytes;
|
||||
if (MOZ_UNLIKELY((!CalculateAllocSizeWithExtra<T, U>(numExtra, &bytes)))) {
|
||||
client()->reportAllocationOverflow();
|
||||
return nullptr;
|
||||
}
|
||||
size_t bytes = sizeof(T) + numExtra * sizeof(U);
|
||||
if (MOZ_UNLIKELY(bytes < sizeof(T))) {
|
||||
client()->reportAllocationOverflow();
|
||||
return nullptr;
|
||||
}
|
||||
T* p = reinterpret_cast<T*>(js_pod_calloc<uint8_t>(bytes));
|
||||
T* p = static_cast<T*>(js_calloc(bytes));
|
||||
if (p) {
|
||||
client()->updateMallocCounter(bytes);
|
||||
return p;
|
||||
@ -184,11 +174,12 @@ struct MallocProvider
|
||||
T* p = maybe_pod_realloc(prior, oldSize, newSize);
|
||||
if (MOZ_LIKELY(p))
|
||||
return p;
|
||||
if (newSize & mozilla::tl::MulOverflowMask<sizeof(T)>::value) {
|
||||
size_t bytes;
|
||||
if (MOZ_UNLIKELY(!CalculateAllocSize<T>(newSize, &bytes))) {
|
||||
client()->reportAllocationOverflow();
|
||||
return nullptr;
|
||||
}
|
||||
p = (T*)client()->onOutOfMemory(AllocFunction::Realloc, newSize * sizeof(T), prior);
|
||||
p = (T*)client()->onOutOfMemory(AllocFunction::Realloc, bytes, prior);
|
||||
if (p && newSize > oldSize)
|
||||
client()->updateMallocCounter((newSize - oldSize) * sizeof(T));
|
||||
return p;
|
||||
|
@ -1460,11 +1460,12 @@ struct JSRuntime : public JS::shadow::Runtime,
|
||||
T* p = pod_calloc<T>(numElems);
|
||||
if (MOZ_LIKELY(!!p))
|
||||
return p;
|
||||
if (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value) {
|
||||
size_t bytes;
|
||||
if (MOZ_UNLIKELY(!js::CalculateAllocSize<T>(numElems, &bytes))) {
|
||||
reportAllocationOverflow();
|
||||
return nullptr;
|
||||
}
|
||||
return (T*)onOutOfMemoryCanGC(js::AllocFunction::Calloc, numElems * sizeof(T));
|
||||
return static_cast<T*>(onOutOfMemoryCanGC(js::AllocFunction::Calloc, bytes));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -1472,11 +1473,12 @@ struct JSRuntime : public JS::shadow::Runtime,
|
||||
T* p2 = pod_realloc<T>(p, oldSize, newSize);
|
||||
if (MOZ_LIKELY(!!p2))
|
||||
return p2;
|
||||
if (newSize & mozilla::tl::MulOverflowMask<sizeof(T)>::value) {
|
||||
size_t bytes;
|
||||
if (MOZ_UNLIKELY(!js::CalculateAllocSize<T>(newSize, &bytes))) {
|
||||
reportAllocationOverflow();
|
||||
return nullptr;
|
||||
}
|
||||
return (T*)onOutOfMemoryCanGC(js::AllocFunction::Realloc, newSize * sizeof(T), p);
|
||||
return static_cast<T*>(onOutOfMemoryCanGC(js::AllocFunction::Realloc, bytes, p));
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user