mirror of
https://github.com/UzixLS/KernelEx.git
synced 2025-07-19 07:21:20 +03:00
import KernelEx-4.5-Beta1
This commit is contained in:
268
apilibs/kexbasen/kernel32/allocator.c
Executable file
268
apilibs/kexbasen/kernel32/allocator.c
Executable file
@ -0,0 +1,268 @@
|
||||
/*
|
||||
* KernelEx
|
||||
* Copyright (C) 2009, Xeno86
|
||||
*
|
||||
* This file is part of KernelEx source code.
|
||||
*
|
||||
* KernelEx is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published
|
||||
* by the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* KernelEx is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/************************************************************************/
|
||||
/* N O T E S */
|
||||
/************************************************************************/
|
||||
|
||||
/* Shared heap and default process heap (GetProcessHeap) is handled by
|
||||
* standard system implementation. This releases us from the hassle of
|
||||
* making special hacks for handling GlobalAlloc and LocalAlloc.
|
||||
* This covers 99% of applications.
|
||||
*
|
||||
* One custom heap is used per process, regardless of the number of
|
||||
* HeapCreate calls. Two distinct handle values are used to indicate
|
||||
* belonging to jemalloc and whether HEAP_GENERATE_EXCEPTIONS flag
|
||||
* was set.
|
||||
* All calls which do not have our handles are forwarded to system.
|
||||
*
|
||||
* One arena is used and TLS usage is disabled for optimal performance
|
||||
* on single processor system. HEAP_NO_SERIALIZE flag is ignored
|
||||
* because there is single heap per process.
|
||||
*/
|
||||
|
||||
/************************************************************************/
|
||||
/* M A C R O S A N D W R A P P E R S */
|
||||
/************************************************************************/
|
||||
|
||||
#define malloc(a) je_malloc(a)
|
||||
#define valloc(a) je_valloc(a)
|
||||
#define calloc(a, b) je_calloc(a, b)
|
||||
#define realloc(a, b) je_realloc(a, b)
|
||||
#define free(a) je_free(a)
|
||||
|
||||
#define MOZ_MEMORY
|
||||
#define MOZ_MEMORY_WINDOWS
|
||||
#define NO_TLS
|
||||
|
||||
#if (_MSC_VER < 1300)
|
||||
#define __STDC_LIMIT_MACROS
|
||||
#include "stdint.h"
|
||||
#endif
|
||||
|
||||
#include "jemalloc/jemalloc.c"
|
||||
|
||||
int* _errno(void)
|
||||
{
|
||||
static int myerrno = 0;
|
||||
return &myerrno;
|
||||
}
|
||||
|
||||
#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
|
||||
#define JM_HEAP_NORM ((HANDLE) TAG('J','E','M','N'))
|
||||
#define JM_HEAP_EXCP ((HANDLE) TAG('J','E','M','E'))
|
||||
|
||||
#define HEAP_SHARED 0x04000000
|
||||
|
||||
BOOL init_jemalloc()
|
||||
{
|
||||
if (malloc_init_hard())
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void uninit_jemalloc()
|
||||
{
|
||||
malloc_print_stats();
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* T H E C O D E */
|
||||
/************************************************************************/
|
||||
|
||||
typedef union
|
||||
{
|
||||
BYTE db;
|
||||
WORD dw;
|
||||
DWORD dd;
|
||||
} UFooter;
|
||||
|
||||
static inline
|
||||
int footer_size(DWORD alloc_bytes)
|
||||
{
|
||||
if (alloc_bytes <= 256 - 1)
|
||||
return 1;
|
||||
else if (alloc_bytes < 64*1024 - 2)
|
||||
return 2;
|
||||
else
|
||||
return 4;
|
||||
}
|
||||
|
||||
static inline
|
||||
int footer_size_for_usable_size(size_t usable)
|
||||
{
|
||||
if (usable <= 256)
|
||||
return 1;
|
||||
else if (usable <= 64*1024)
|
||||
return 2;
|
||||
else
|
||||
return 4;
|
||||
}
|
||||
|
||||
static inline
|
||||
DWORD read_footer(const void* ptr, size_t usable, int fs)
|
||||
{
|
||||
UFooter* footer;
|
||||
if (!ptr)
|
||||
return 0;
|
||||
footer = (UFooter*) ((DWORD) ptr + usable - fs);
|
||||
if (fs == sizeof(BYTE))
|
||||
return footer->db;
|
||||
else if (fs == sizeof(WORD))
|
||||
return footer->dw;
|
||||
else
|
||||
return footer->dd;
|
||||
}
|
||||
|
||||
static inline
|
||||
void write_footer(void* ptr, size_t usable, int fs, DWORD value)
|
||||
{
|
||||
UFooter* footer = (UFooter*) ((DWORD) ptr + usable - fs);
|
||||
if (fs == sizeof(BYTE))
|
||||
footer->db = (BYTE) value;
|
||||
else if (fs == sizeof(WORD))
|
||||
footer->dw = (WORD) value;
|
||||
else
|
||||
footer->dd = (DWORD) value;
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT HeapCreate_new=HeapCreate */
|
||||
HANDLE WINAPI HeapCreate_new(DWORD flOptions, DWORD dwInitialSize, DWORD dwMaximumSize)
|
||||
{
|
||||
if (flOptions & HEAP_SHARED)
|
||||
return HeapCreate(flOptions, dwInitialSize, dwMaximumSize);
|
||||
if (flOptions & HEAP_GENERATE_EXCEPTIONS)
|
||||
return JM_HEAP_EXCP;
|
||||
else
|
||||
return JM_HEAP_NORM;
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT HeapDestroy_new=HeapDestroy */
|
||||
BOOL WINAPI HeapDestroy_new(HANDLE hHeap)
|
||||
{
|
||||
if (hHeap == JM_HEAP_NORM || hHeap == JM_HEAP_EXCP)
|
||||
return TRUE;
|
||||
else
|
||||
return HeapDestroy(hHeap);
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT HeapAlloc_new=HeapAlloc */
|
||||
LPVOID WINAPI HeapAlloc_new(HANDLE hHeap, DWORD dwFlags, DWORD dwBytes)
|
||||
{
|
||||
if (hHeap == JM_HEAP_NORM || hHeap == JM_HEAP_EXCP)
|
||||
{
|
||||
LPVOID ret;
|
||||
int fs = footer_size(dwBytes);
|
||||
|
||||
if (dwFlags & HEAP_ZERO_MEMORY)
|
||||
ret = calloc(1, dwBytes + fs);
|
||||
else
|
||||
ret = malloc(dwBytes + fs);
|
||||
if (!ret && (hHeap == JM_HEAP_EXCP || (dwFlags & HEAP_GENERATE_EXCEPTIONS)))
|
||||
RaiseException(STATUS_NO_MEMORY, 0, 0, NULL);
|
||||
|
||||
if (ret)
|
||||
write_footer(ret, malloc_usable_size(ret), fs, dwBytes);
|
||||
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
return HeapAlloc(hHeap, dwFlags, dwBytes);
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT HeapFree_new=HeapFree */
|
||||
BOOL WINAPI HeapFree_new(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem)
|
||||
{
|
||||
if (hHeap == JM_HEAP_NORM || hHeap == JM_HEAP_EXCP)
|
||||
{
|
||||
free(lpMem);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return HeapFree(hHeap, dwFlags, lpMem);
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT HeapSize_new=HeapSize */
|
||||
DWORD WINAPI HeapSize_new(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem)
|
||||
{
|
||||
if (hHeap == JM_HEAP_NORM || hHeap == JM_HEAP_EXCP)
|
||||
{
|
||||
size_t usable = malloc_usable_size(lpMem);
|
||||
int fs = footer_size_for_usable_size(usable);
|
||||
|
||||
return read_footer(lpMem, usable, fs);
|
||||
}
|
||||
else
|
||||
return HeapSize(hHeap, dwFlags, lpMem);
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT HeapReAlloc_new=HeapReAlloc */
|
||||
LPVOID WINAPI HeapReAlloc_new(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, DWORD dwBytes)
|
||||
{
|
||||
if (hHeap == JM_HEAP_NORM || hHeap == JM_HEAP_EXCP)
|
||||
{
|
||||
LPVOID ret;
|
||||
int fs = footer_size(dwBytes);
|
||||
size_t usable = malloc_usable_size(lpMem);
|
||||
|
||||
if (dwFlags & HEAP_REALLOC_IN_PLACE_ONLY)
|
||||
{
|
||||
if (usable > dwBytes + fs)
|
||||
{
|
||||
size_t fsu = footer_size_for_usable_size(usable);
|
||||
if (dwFlags & HEAP_ZERO_MEMORY)
|
||||
{
|
||||
DWORD old = read_footer(lpMem, usable, fsu);
|
||||
if (dwBytes > old)
|
||||
memset((void*) ((DWORD) lpMem + old), 0, dwBytes - old);
|
||||
}
|
||||
|
||||
write_footer(lpMem, usable, fsu, dwBytes);
|
||||
ret = lpMem;
|
||||
}
|
||||
else
|
||||
ret = NULL;
|
||||
}
|
||||
else if (dwFlags & HEAP_ZERO_MEMORY)
|
||||
{
|
||||
DWORD old = read_footer(lpMem, usable, footer_size_for_usable_size(usable));
|
||||
ret = realloc(lpMem, dwBytes + fs);
|
||||
if (ret)
|
||||
{
|
||||
if (dwBytes > old)
|
||||
memset((void*) ((DWORD) ret + old), 0, dwBytes - old);
|
||||
write_footer(ret, malloc_usable_size(ret), fs, dwBytes);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = realloc(lpMem, dwBytes + fs);
|
||||
if (ret)
|
||||
write_footer(ret, malloc_usable_size(ret), fs, dwBytes);
|
||||
}
|
||||
if (!ret && (hHeap == JM_HEAP_EXCP || (dwFlags & HEAP_GENERATE_EXCEPTIONS)))
|
||||
RaiseException(STATUS_NO_MEMORY, 0, 0, NULL);
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
return HeapReAlloc(hHeap, dwFlags, lpMem, dwBytes);
|
||||
}
|
||||
|
Reference in New Issue
Block a user