mirror of
https://github.com/decompals/wibo.git
synced 2025-10-16 15:15:10 +00:00
Improve heapapi implementation
This commit is contained in:
parent
ce57eb44a8
commit
2ffc56f5c2
@ -82,6 +82,7 @@ FetchContent_MakeAvailable(mimalloc)
|
|||||||
|
|
||||||
# Disable `note: the alignment of '_Atomic long long int' fields changed in GCC 11.1`
|
# Disable `note: the alignment of '_Atomic long long int' fields changed in GCC 11.1`
|
||||||
target_compile_options(mimalloc-obj PRIVATE -Wno-psabi)
|
target_compile_options(mimalloc-obj PRIVATE -Wno-psabi)
|
||||||
|
target_compile_definitions(mimalloc-obj PRIVATE MI_USE_BUILTIN_THREAD_POINTER=1)
|
||||||
|
|
||||||
if (WIBO_ENABLE_LIBURING)
|
if (WIBO_ENABLE_LIBURING)
|
||||||
FetchContent_Declare(
|
FetchContent_Declare(
|
||||||
|
@ -26,7 +26,6 @@ void ensureProcessHeapInitialized() {
|
|||||||
if (!record) {
|
if (!record) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
record->heap = heap;
|
|
||||||
record->isProcessHeap = true;
|
record->isProcessHeap = true;
|
||||||
g_processHeapRecord = record.get();
|
g_processHeapRecord = record.get();
|
||||||
g_processHeapHandle = wibo::handles().alloc(std::move(record), 0, 0);
|
g_processHeapHandle = wibo::handles().alloc(std::move(record), 0, 0);
|
||||||
@ -91,31 +90,23 @@ HANDLE WIN_FUNC HeapCreate(DWORD flOptions, SIZE_T dwInitialSize, SIZE_T dwMaxim
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto record = make_pin<HeapObject>(heap);
|
auto record = make_pin<HeapObject>(heap);
|
||||||
record->heap = heap;
|
|
||||||
record->createFlags = flOptions;
|
record->createFlags = flOptions;
|
||||||
record->initialSize = dwInitialSize;
|
record->initialSize = dwInitialSize;
|
||||||
record->maximumSize = dwMaximumSize;
|
record->maximumSize = dwMaximumSize;
|
||||||
record->isProcessHeap = false;
|
return wibo::handles().alloc(std::move(record), 0, 0);
|
||||||
|
|
||||||
HANDLE handle = wibo::handles().alloc(std::move(record), 0, 0);
|
|
||||||
return handle;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL WIN_FUNC HeapDestroy(HANDLE hHeap) {
|
BOOL WIN_FUNC HeapDestroy(HANDLE hHeap) {
|
||||||
HOST_CONTEXT_GUARD();
|
HOST_CONTEXT_GUARD();
|
||||||
DEBUG_LOG("HeapDestroy(%p)\n", hHeap);
|
DEBUG_LOG("HeapDestroy(%p)\n", hHeap);
|
||||||
auto record = wibo::handles().getAs<HeapObject>(hHeap);
|
auto record = wibo::handles().getAs<HeapObject>(hHeap);
|
||||||
if (!record) {
|
if (!record || !record->isOwner() || record->isProcessHeap) {
|
||||||
wibo::lastError = ERROR_INVALID_HANDLE;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
std::lock_guard lk(record->m);
|
|
||||||
if (record->isProcessHeap || record->heap == nullptr) {
|
|
||||||
wibo::lastError = ERROR_INVALID_HANDLE;
|
wibo::lastError = ERROR_INVALID_HANDLE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
mi_heap_destroy(record->heap);
|
mi_heap_destroy(record->heap);
|
||||||
record->heap = nullptr;
|
record->heap = nullptr;
|
||||||
|
wibo::handles().release(hHeap);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,15 +123,10 @@ BOOL WIN_FUNC HeapSetInformation(HANDLE HeapHandle, HEAP_INFORMATION_CLASS HeapI
|
|||||||
DEBUG_LOG("HeapSetInformation(%p, %d, %p, %zu)\n", HeapHandle, static_cast<int>(HeapInformationClass),
|
DEBUG_LOG("HeapSetInformation(%p, %d, %p, %zu)\n", HeapHandle, static_cast<int>(HeapInformationClass),
|
||||||
HeapInformation, HeapInformationLength);
|
HeapInformation, HeapInformationLength);
|
||||||
auto record = wibo::handles().getAs<HeapObject>(HeapHandle);
|
auto record = wibo::handles().getAs<HeapObject>(HeapHandle);
|
||||||
if (!record) {
|
if (!record || !record->canAccess()) {
|
||||||
wibo::lastError = ERROR_INVALID_HANDLE;
|
wibo::lastError = ERROR_INVALID_HANDLE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
std::lock_guard lk(record->m);
|
|
||||||
if (!record->heap) {
|
|
||||||
wibo::lastError = ERROR_INVALID_PARAMETER;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
switch (HeapInformationClass) {
|
switch (HeapInformationClass) {
|
||||||
case HeapCompatibilityInformation: {
|
case HeapCompatibilityInformation: {
|
||||||
if (!HeapInformation || HeapInformationLength < sizeof(ULONG)) {
|
if (!HeapInformation || HeapInformationLength < sizeof(ULONG)) {
|
||||||
@ -163,51 +149,39 @@ BOOL WIN_FUNC HeapSetInformation(HANDLE HeapHandle, HEAP_INFORMATION_CLASS HeapI
|
|||||||
|
|
||||||
LPVOID WIN_FUNC HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes) {
|
LPVOID WIN_FUNC HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes) {
|
||||||
HOST_CONTEXT_GUARD();
|
HOST_CONTEXT_GUARD();
|
||||||
DEBUG_LOG("HeapAlloc(%p, 0x%x, %zu) ", hHeap, dwFlags, dwBytes);
|
VERBOSE_LOG("HeapAlloc(%p, 0x%x, %zu) ", hHeap, dwFlags, dwBytes);
|
||||||
auto record = wibo::handles().getAs<HeapObject>(hHeap);
|
auto record = wibo::handles().getAs<HeapObject>(hHeap);
|
||||||
if (!record) {
|
if (!record || !record->canAccess()) {
|
||||||
DEBUG_LOG("-> NULL\n");
|
VERBOSE_LOG("-> NULL\n");
|
||||||
wibo::lastError = ERROR_INVALID_HANDLE;
|
wibo::lastError = ERROR_INVALID_HANDLE;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
std::lock_guard lk(record->m);
|
|
||||||
if (!record->heap) {
|
|
||||||
DEBUG_LOG("-> NULL\n");
|
|
||||||
wibo::lastError = ERROR_INVALID_PARAMETER;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
void *mem = heapAllocFromRecord(record.get(), dwFlags, dwBytes);
|
void *mem = heapAllocFromRecord(record.get(), dwFlags, dwBytes);
|
||||||
DEBUG_LOG("-> %p\n", mem);
|
VERBOSE_LOG("-> %p\n", mem);
|
||||||
return mem;
|
return mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
LPVOID WIN_FUNC HeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dwBytes) {
|
LPVOID WIN_FUNC HeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dwBytes) {
|
||||||
HOST_CONTEXT_GUARD();
|
HOST_CONTEXT_GUARD();
|
||||||
DEBUG_LOG("HeapReAlloc(%p, 0x%x, %p, %zu) ", hHeap, dwFlags, lpMem, dwBytes);
|
VERBOSE_LOG("HeapReAlloc(%p, 0x%x, %p, %zu) ", hHeap, dwFlags, lpMem, dwBytes);
|
||||||
auto record = wibo::handles().getAs<HeapObject>(hHeap);
|
auto record = wibo::handles().getAs<HeapObject>(hHeap);
|
||||||
if (!record) {
|
if (!record || !record->canAccess()) {
|
||||||
DEBUG_LOG("-> NULL\n");
|
VERBOSE_LOG("-> NULL\n");
|
||||||
wibo::lastError = ERROR_INVALID_HANDLE;
|
wibo::lastError = ERROR_INVALID_HANDLE;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
std::lock_guard lk(record->m);
|
|
||||||
if (!record->heap) {
|
|
||||||
DEBUG_LOG("-> NULL\n");
|
|
||||||
wibo::lastError = ERROR_INVALID_PARAMETER;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
if (lpMem == nullptr) {
|
if (lpMem == nullptr) {
|
||||||
void *alloc = heapAllocFromRecord(record.get(), dwFlags, dwBytes);
|
void *alloc = heapAllocFromRecord(record.get(), dwFlags, dwBytes);
|
||||||
DEBUG_LOG("-> %p (alloc)\n", alloc);
|
VERBOSE_LOG("-> %p (alloc)\n", alloc);
|
||||||
return alloc;
|
return alloc;
|
||||||
}
|
}
|
||||||
// if (!mi_heap_check_owned(record->heap, lpMem)) {
|
if (!mi_heap_check_owned(record->heap, lpMem)) {
|
||||||
// DEBUG_LOG("-> NULL (not owned)\n");
|
VERBOSE_LOG("-> NULL (not owned)\n");
|
||||||
// wibo::lastError = ERROR_INVALID_PARAMETER;
|
wibo::lastError = ERROR_INVALID_PARAMETER;
|
||||||
// return nullptr;
|
return nullptr;
|
||||||
// }
|
}
|
||||||
if ((record->createFlags | dwFlags) & HEAP_GENERATE_EXCEPTIONS) {
|
if ((record->createFlags | dwFlags) & HEAP_GENERATE_EXCEPTIONS) {
|
||||||
DEBUG_LOG("-> NULL (exceptions unsupported)\n");
|
VERBOSE_LOG("-> NULL (exceptions unsupported)\n");
|
||||||
wibo::lastError = ERROR_NOT_SUPPORTED;
|
wibo::lastError = ERROR_NOT_SUPPORTED;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -216,10 +190,10 @@ LPVOID WIN_FUNC HeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dw
|
|||||||
if (dwBytes == 0) {
|
if (dwBytes == 0) {
|
||||||
if (!inplaceOnly) {
|
if (!inplaceOnly) {
|
||||||
mi_free(lpMem);
|
mi_free(lpMem);
|
||||||
DEBUG_LOG("-> NULL (freed)\n");
|
VERBOSE_LOG("-> NULL (freed)\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
DEBUG_LOG("-> NULL (zero size with in-place flag)\n");
|
VERBOSE_LOG("-> NULL (zero size with in-place flag)\n");
|
||||||
wibo::lastError = ERROR_NOT_ENOUGH_MEMORY;
|
wibo::lastError = ERROR_NOT_ENOUGH_MEMORY;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -228,11 +202,11 @@ LPVOID WIN_FUNC HeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dw
|
|||||||
const SIZE_T oldSize = mi_usable_size(lpMem);
|
const SIZE_T oldSize = mi_usable_size(lpMem);
|
||||||
if (inplaceOnly || requestSize <= oldSize) {
|
if (inplaceOnly || requestSize <= oldSize) {
|
||||||
if (requestSize > oldSize) {
|
if (requestSize > oldSize) {
|
||||||
DEBUG_LOG("-> NULL (cannot grow in place)\n");
|
VERBOSE_LOG("-> NULL (cannot grow in place)\n");
|
||||||
wibo::lastError = ERROR_NOT_ENOUGH_MEMORY;
|
wibo::lastError = ERROR_NOT_ENOUGH_MEMORY;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
DEBUG_LOG("-> %p (in-place)\n", lpMem);
|
VERBOSE_LOG("-> %p (in-place)\n", lpMem);
|
||||||
return lpMem;
|
return lpMem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,30 +225,27 @@ LPVOID WIN_FUNC HeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dw
|
|||||||
if (isExecutableHeap(record.get())) {
|
if (isExecutableHeap(record.get())) {
|
||||||
tryMarkExecutable(ret);
|
tryMarkExecutable(ret);
|
||||||
}
|
}
|
||||||
DEBUG_LOG("-> %p\n", ret);
|
VERBOSE_LOG("-> %p\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
SIZE_T WIN_FUNC HeapSize(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem) {
|
SIZE_T WIN_FUNC HeapSize(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem) {
|
||||||
HOST_CONTEXT_GUARD();
|
HOST_CONTEXT_GUARD();
|
||||||
DEBUG_LOG("HeapSize(%p, 0x%x, %p)\n", hHeap, dwFlags, lpMem);
|
VERBOSE_LOG("HeapSize(%p, 0x%x, %p)\n", hHeap, dwFlags, lpMem);
|
||||||
(void)dwFlags;
|
(void)dwFlags;
|
||||||
auto record = wibo::handles().getAs<HeapObject>(hHeap);
|
auto record = wibo::handles().getAs<HeapObject>(hHeap);
|
||||||
if (!record) {
|
if (!record || !record->canAccess()) {
|
||||||
|
VERBOSE_LOG("-> ERROR_INVALID_HANDLE\n");
|
||||||
wibo::lastError = ERROR_INVALID_HANDLE;
|
wibo::lastError = ERROR_INVALID_HANDLE;
|
||||||
return static_cast<SIZE_T>(-1);
|
return static_cast<SIZE_T>(-1);
|
||||||
}
|
}
|
||||||
std::lock_guard lk(record->m);
|
|
||||||
if (!record->heap) {
|
|
||||||
wibo::lastError = ERROR_INVALID_PARAMETER;
|
|
||||||
return static_cast<SIZE_T>(-1);
|
|
||||||
}
|
|
||||||
if (!lpMem) {
|
if (!lpMem) {
|
||||||
|
VERBOSE_LOG("-> ERROR_INVALID_PARAMETER\n");
|
||||||
wibo::lastError = ERROR_INVALID_PARAMETER;
|
wibo::lastError = ERROR_INVALID_PARAMETER;
|
||||||
return static_cast<SIZE_T>(-1);
|
return static_cast<SIZE_T>(-1);
|
||||||
}
|
}
|
||||||
if (!mi_heap_check_owned(record->heap, const_cast<LPVOID>(lpMem))) {
|
if (!mi_heap_check_owned(record->heap, lpMem)) {
|
||||||
DEBUG_LOG("HeapSize: block %p not owned by heap %p\n", lpMem, record->heap);
|
VERBOSE_LOG("-> ERROR_INVALID_PARAMETER (not owned)\n");
|
||||||
wibo::lastError = ERROR_INVALID_PARAMETER;
|
wibo::lastError = ERROR_INVALID_PARAMETER;
|
||||||
return static_cast<SIZE_T>(-1);
|
return static_cast<SIZE_T>(-1);
|
||||||
}
|
}
|
||||||
@ -284,30 +255,24 @@ SIZE_T WIN_FUNC HeapSize(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem) {
|
|||||||
|
|
||||||
BOOL WIN_FUNC HeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) {
|
BOOL WIN_FUNC HeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) {
|
||||||
HOST_CONTEXT_GUARD();
|
HOST_CONTEXT_GUARD();
|
||||||
DEBUG_LOG("HeapFree(%p, 0x%x, %p)\n", hHeap, dwFlags, lpMem);
|
VERBOSE_LOG("HeapFree(%p, 0x%x, %p)\n", hHeap, dwFlags, lpMem);
|
||||||
(void)dwFlags;
|
(void)dwFlags;
|
||||||
if (lpMem == nullptr) {
|
if (lpMem == nullptr) {
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
auto record = wibo::handles().getAs<HeapObject>(hHeap);
|
auto record = wibo::handles().getAs<HeapObject>(hHeap);
|
||||||
if (!record) {
|
if (!record || !record->canAccess()) {
|
||||||
DEBUG_LOG("-> INVALID_HANDLE\n");
|
VERBOSE_LOG("-> ERROR_INVALID_HANDLE\n");
|
||||||
wibo::lastError = ERROR_INVALID_HANDLE;
|
wibo::lastError = ERROR_INVALID_HANDLE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
std::lock_guard lk(record->m);
|
|
||||||
if (!record->heap) {
|
|
||||||
DEBUG_LOG("-> INVALID_PARAMETER\n");
|
|
||||||
wibo::lastError = ERROR_INVALID_PARAMETER;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if (!mi_heap_check_owned(record->heap, lpMem)) {
|
if (!mi_heap_check_owned(record->heap, lpMem)) {
|
||||||
DEBUG_LOG("-> INVALID_PARAMETER (not owned)\n");
|
VERBOSE_LOG("-> ERROR_INVALID_PARAMETER (not owned)\n");
|
||||||
wibo::lastError = ERROR_INVALID_PARAMETER;
|
wibo::lastError = ERROR_INVALID_PARAMETER;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
mi_free(lpMem);
|
mi_free(lpMem);
|
||||||
DEBUG_LOG("-> SUCCESS\n");
|
VERBOSE_LOG("-> SUCCESS\n");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,16 +153,19 @@ struct SemaphoreObject final : WaitableObject {
|
|||||||
struct HeapObject : public ObjectBase {
|
struct HeapObject : public ObjectBase {
|
||||||
static constexpr ObjectType kType = ObjectType::Heap;
|
static constexpr ObjectType kType = ObjectType::Heap;
|
||||||
|
|
||||||
std::mutex m;
|
|
||||||
mi_heap_t *heap;
|
mi_heap_t *heap;
|
||||||
|
const pthread_t owner;
|
||||||
DWORD createFlags = 0;
|
DWORD createFlags = 0;
|
||||||
SIZE_T initialSize = 0;
|
SIZE_T initialSize = 0;
|
||||||
SIZE_T maximumSize = 0;
|
SIZE_T maximumSize = 0;
|
||||||
DWORD compatibility = 0;
|
DWORD compatibility = 0;
|
||||||
bool isProcessHeap = false;
|
bool isProcessHeap = false;
|
||||||
|
|
||||||
explicit HeapObject(mi_heap_t *heap) : ObjectBase(kType), heap(heap) {}
|
explicit HeapObject(mi_heap_t *heap) : ObjectBase(kType), heap(heap), owner(pthread_self()) {}
|
||||||
~HeapObject() override;
|
~HeapObject() override;
|
||||||
|
|
||||||
|
[[nodiscard]] inline bool isOwner() const { return pthread_equal(owner, pthread_self()); }
|
||||||
|
[[nodiscard]] inline bool canAccess() const { return (isProcessHeap || isOwner()) && heap != nullptr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
inline constexpr uintptr_t kPseudoCurrentProcessHandleValue = static_cast<uintptr_t>(-1);
|
inline constexpr uintptr_t kPseudoCurrentProcessHandleValue = static_cast<uintptr_t>(-1);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user