#include "config.h"
#include "Gigacage.h"
#include <wtf/Atomics.h>
#include <wtf/PageBlock.h>
#include <wtf/OSAllocator.h>
#if defined(USE_SYSTEM_MALLOC) && USE_SYSTEM_MALLOC
char g_gigacageBasePtrs[GIGACAGE_BASE_PTRS_SIZE];
namespace Gigacage {
void* tryMalloc(Kind, size_t size)
{
return FastMalloc::tryMalloc(size);
}
void* tryAllocateZeroedVirtualPages(Kind, size_t size)
{
size = roundUpToMultipleOf(WTF::pageSize(), size);
void* result = OSAllocator::reserveAndCommit(size);
#if !ASSERT_DISABLED
if (result) {
for (size_t i = 0; i < size / sizeof(uintptr_t); ++i)
ASSERT(static_cast<uintptr_t*>(result)[i] == 0);
}
#endif
return result;
}
void freeVirtualPages(Kind, void* basePtr, size_t size)
{
OSAllocator::decommitAndRelease(basePtr, size);
}
} #else
#include <bmalloc/bmalloc.h>
namespace Gigacage {
void* tryAlignedMalloc(Kind kind, size_t alignment, size_t size)
{
void* result = bmalloc::api::tryMemalign(alignment, size, bmalloc::heapKind(kind));
WTF::compilerFence();
return result;
}
void alignedFree(Kind kind, void* p)
{
if (!p)
return;
RELEASE_ASSERT(isCaged(kind, p));
bmalloc::api::free(p, bmalloc::heapKind(kind));
WTF::compilerFence();
}
void* tryMalloc(Kind kind, size_t size)
{
void* result = bmalloc::api::tryMalloc(size, bmalloc::heapKind(kind));
WTF::compilerFence();
return result;
}
void free(Kind kind, void* p)
{
if (!p)
return;
RELEASE_ASSERT(isCaged(kind, p));
bmalloc::api::free(p, bmalloc::heapKind(kind));
WTF::compilerFence();
}
void* tryAllocateZeroedVirtualPages(Kind kind, size_t size)
{
void* result = bmalloc::api::tryLargeZeroedMemalignVirtual(WTF::pageSize(), size, bmalloc::heapKind(kind));
WTF::compilerFence();
return result;
}
void freeVirtualPages(Kind kind, void* basePtr, size_t)
{
if (!basePtr)
return;
RELEASE_ASSERT(isCaged(kind, basePtr));
bmalloc::api::freeLargeVirtual(basePtr, bmalloc::heapKind(kind));
WTF::compilerFence();
}
} #endif
namespace Gigacage {
void* tryMallocArray(Kind kind, size_t numElements, size_t elementSize)
{
Checked<size_t, RecordOverflow> checkedSize = elementSize;
checkedSize *= numElements;
if (checkedSize.hasOverflowed())
return nullptr;
return tryMalloc(kind, checkedSize.unsafeGet());
}
void* malloc(Kind kind, size_t size)
{
void* result = tryMalloc(kind, size);
RELEASE_ASSERT(result);
return result;
}
void* mallocArray(Kind kind, size_t numElements, size_t elementSize)
{
void* result = tryMallocArray(kind, numElements, elementSize);
RELEASE_ASSERT(result);
return result;
}
}