mirror of
https://github.com/reactos/reactos.git
synced 2025-01-15 18:43:27 +00:00
[CRT] Use the original wine heap functions
This commit is contained in:
parent
cf40758d76
commit
c47506a5f4
2 changed files with 127 additions and 15 deletions
|
@ -5,6 +5,7 @@ extern int BlockEnvToEnvironA(void);
|
||||||
extern int BlockEnvToEnvironW(void);
|
extern int BlockEnvToEnvironW(void);
|
||||||
extern void FreeEnvironment(char **environment);
|
extern void FreeEnvironment(char **environment);
|
||||||
|
|
||||||
|
extern BOOL msvcrt_init_heap(void);
|
||||||
extern void msvcrt_init_mt_locks(void);
|
extern void msvcrt_init_mt_locks(void);
|
||||||
extern void msvcrt_init_io(void);
|
extern void msvcrt_init_io(void);
|
||||||
|
|
||||||
|
@ -34,6 +35,9 @@ crt_process_init(void)
|
||||||
if (!msvcrt_init_tls())
|
if (!msvcrt_init_tls())
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
if (!msvcrt_init_heap())
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
if (BlockEnvToEnvironA() < 0)
|
if (BlockEnvToEnvironA() < 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,9 @@
|
||||||
((((DWORD_PTR)((char *)ptr + alignment + sizeof(void *) + offset)) & \
|
((((DWORD_PTR)((char *)ptr + alignment + sizeof(void *) + offset)) & \
|
||||||
~(alignment - 1)) - offset))
|
~(alignment - 1)) - offset))
|
||||||
|
|
||||||
|
#define SB_HEAP_ALIGN 16
|
||||||
|
|
||||||
|
static HANDLE heap, sb_heap;
|
||||||
|
|
||||||
typedef int (CDECL *MSVCRT_new_handler_func)(MSVCRT_size_t size);
|
typedef int (CDECL *MSVCRT_new_handler_func)(MSVCRT_size_t size);
|
||||||
|
|
||||||
|
@ -67,6 +70,78 @@ static unsigned int MSVCRT_amblksiz = 16;
|
||||||
/* FIXME - According to documentation it should be 480 bytes, at runtime default is 0 */
|
/* FIXME - According to documentation it should be 480 bytes, at runtime default is 0 */
|
||||||
static MSVCRT_size_t MSVCRT_sbh_threshold = 0;
|
static MSVCRT_size_t MSVCRT_sbh_threshold = 0;
|
||||||
|
|
||||||
|
static void* msvcrt_heap_alloc(DWORD flags, MSVCRT_size_t size)
|
||||||
|
{
|
||||||
|
if(size < MSVCRT_sbh_threshold)
|
||||||
|
{
|
||||||
|
void *memblock, *temp, **saved;
|
||||||
|
|
||||||
|
temp = HeapAlloc(sb_heap, flags, size+sizeof(void*)+SB_HEAP_ALIGN);
|
||||||
|
if(!temp) return NULL;
|
||||||
|
|
||||||
|
memblock = ALIGN_PTR(temp, SB_HEAP_ALIGN, 0);
|
||||||
|
saved = SAVED_PTR(memblock);
|
||||||
|
*saved = temp;
|
||||||
|
return memblock;
|
||||||
|
}
|
||||||
|
|
||||||
|
return HeapAlloc(heap, flags, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void* msvcrt_heap_realloc(DWORD flags, void *ptr, MSVCRT_size_t size)
|
||||||
|
{
|
||||||
|
if(sb_heap && ptr && !HeapValidate(heap, 0, ptr))
|
||||||
|
{
|
||||||
|
/* TODO: move data to normal heap if it exceeds sbh_threshold limit */
|
||||||
|
void *memblock, *temp, **saved;
|
||||||
|
MSVCRT_size_t old_padding, new_padding, old_size;
|
||||||
|
|
||||||
|
saved = SAVED_PTR(ptr);
|
||||||
|
old_padding = (char*)ptr - (char*)*saved;
|
||||||
|
old_size = HeapSize(sb_heap, 0, *saved);
|
||||||
|
if(old_size == -1)
|
||||||
|
return NULL;
|
||||||
|
old_size -= old_padding;
|
||||||
|
|
||||||
|
temp = HeapReAlloc(sb_heap, flags, *saved, size+sizeof(void*)+SB_HEAP_ALIGN);
|
||||||
|
if(!temp) return NULL;
|
||||||
|
|
||||||
|
memblock = ALIGN_PTR(temp, SB_HEAP_ALIGN, 0);
|
||||||
|
saved = SAVED_PTR(memblock);
|
||||||
|
new_padding = (char*)memblock - (char*)temp;
|
||||||
|
|
||||||
|
if(new_padding != old_padding)
|
||||||
|
memmove(memblock, (char*)temp+old_padding, old_size>size ? size : old_size);
|
||||||
|
|
||||||
|
*saved = temp;
|
||||||
|
return memblock;
|
||||||
|
}
|
||||||
|
|
||||||
|
return HeapReAlloc(heap, flags, ptr, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL msvcrt_heap_free(void *ptr)
|
||||||
|
{
|
||||||
|
if(sb_heap && ptr && !HeapValidate(heap, 0, ptr))
|
||||||
|
{
|
||||||
|
void **saved = SAVED_PTR(ptr);
|
||||||
|
return HeapFree(sb_heap, 0, *saved);
|
||||||
|
}
|
||||||
|
|
||||||
|
return HeapFree(heap, 0, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static MSVCRT_size_t msvcrt_heap_size(void *ptr)
|
||||||
|
{
|
||||||
|
if(sb_heap && ptr && !HeapValidate(heap, 0, ptr))
|
||||||
|
{
|
||||||
|
void **saved = SAVED_PTR(ptr);
|
||||||
|
return HeapSize(sb_heap, 0, *saved);
|
||||||
|
}
|
||||||
|
|
||||||
|
return HeapSize(heap, 0, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* ??2@YAPAXI@Z (MSVCRT.@)
|
* ??2@YAPAXI@Z (MSVCRT.@)
|
||||||
*/
|
*/
|
||||||
|
@ -78,7 +153,7 @@ void* CDECL MSVCRT_operator_new(MSVCRT_size_t size)
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
retval = HeapAlloc(GetProcessHeap(), 0, size);
|
retval = msvcrt_heap_alloc(0, size);
|
||||||
if(retval)
|
if(retval)
|
||||||
{
|
{
|
||||||
TRACE("(%ld) returning %p\n", size, retval);
|
TRACE("(%ld) returning %p\n", size, retval);
|
||||||
|
@ -117,7 +192,7 @@ void* CDECL MSVCRT_operator_new_dbg(MSVCRT_size_t size, int type, const char *fi
|
||||||
void CDECL MSVCRT_operator_delete(void *mem)
|
void CDECL MSVCRT_operator_delete(void *mem)
|
||||||
{
|
{
|
||||||
TRACE("(%p)\n", mem);
|
TRACE("(%p)\n", mem);
|
||||||
HeapFree(GetProcessHeap(), 0, mem);
|
msvcrt_heap_free(mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -191,7 +266,7 @@ int CDECL _callnewh(MSVCRT_size_t size)
|
||||||
*/
|
*/
|
||||||
void* CDECL _expand(void* mem, MSVCRT_size_t size)
|
void* CDECL _expand(void* mem, MSVCRT_size_t size)
|
||||||
{
|
{
|
||||||
return HeapReAlloc(GetProcessHeap(), HEAP_REALLOC_IN_PLACE_ONLY, mem, size);
|
return msvcrt_heap_realloc(HEAP_REALLOC_IN_PLACE_ONLY, mem, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
|
@ -199,7 +274,8 @@ void* CDECL _expand(void* mem, MSVCRT_size_t size)
|
||||||
*/
|
*/
|
||||||
int CDECL _heapchk(void)
|
int CDECL _heapchk(void)
|
||||||
{
|
{
|
||||||
if (!HeapValidate( GetProcessHeap(), 0, NULL))
|
if (!HeapValidate(heap, 0, NULL) ||
|
||||||
|
(sb_heap && !HeapValidate(sb_heap, 0, NULL)))
|
||||||
{
|
{
|
||||||
_dosmaperr(GetLastError());
|
_dosmaperr(GetLastError());
|
||||||
return MSVCRT__HEAPBADNODE;
|
return MSVCRT__HEAPBADNODE;
|
||||||
|
@ -212,7 +288,8 @@ int CDECL _heapchk(void)
|
||||||
*/
|
*/
|
||||||
int CDECL _heapmin(void)
|
int CDECL _heapmin(void)
|
||||||
{
|
{
|
||||||
if (!HeapCompact( GetProcessHeap(), 0 ))
|
if (!HeapCompact( heap, 0 ) ||
|
||||||
|
(sb_heap && !HeapCompact( sb_heap, 0 )))
|
||||||
{
|
{
|
||||||
if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
|
if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
|
||||||
_dosmaperr(GetLastError());
|
_dosmaperr(GetLastError());
|
||||||
|
@ -228,13 +305,16 @@ int CDECL _heapwalk(struct MSVCRT__heapinfo* next)
|
||||||
{
|
{
|
||||||
PROCESS_HEAP_ENTRY phe;
|
PROCESS_HEAP_ENTRY phe;
|
||||||
|
|
||||||
|
if (sb_heap)
|
||||||
|
FIXME("small blocks heap not supported\n");
|
||||||
|
|
||||||
LOCK_HEAP;
|
LOCK_HEAP;
|
||||||
phe.lpData = next->_pentry;
|
phe.lpData = next->_pentry;
|
||||||
phe.cbData = (DWORD)next->_size;
|
phe.cbData = (DWORD)next->_size;
|
||||||
phe.wFlags = next->_useflag == MSVCRT__USEDENTRY ? PROCESS_HEAP_ENTRY_BUSY : 0;
|
phe.wFlags = next->_useflag == MSVCRT__USEDENTRY ? PROCESS_HEAP_ENTRY_BUSY : 0;
|
||||||
|
|
||||||
if (phe.lpData && phe.wFlags & PROCESS_HEAP_ENTRY_BUSY &&
|
if (phe.lpData && phe.wFlags & PROCESS_HEAP_ENTRY_BUSY &&
|
||||||
!HeapValidate( GetProcessHeap(), 0, phe.lpData ))
|
!HeapValidate( heap, 0, phe.lpData ))
|
||||||
{
|
{
|
||||||
UNLOCK_HEAP;
|
UNLOCK_HEAP;
|
||||||
_dosmaperr(GetLastError());
|
_dosmaperr(GetLastError());
|
||||||
|
@ -243,7 +323,7 @@ int CDECL _heapwalk(struct MSVCRT__heapinfo* next)
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (!HeapWalk( GetProcessHeap(), &phe ))
|
if (!HeapWalk( heap, &phe ))
|
||||||
{
|
{
|
||||||
UNLOCK_HEAP;
|
UNLOCK_HEAP;
|
||||||
if (GetLastError() == ERROR_NO_MORE_ITEMS)
|
if (GetLastError() == ERROR_NO_MORE_ITEMS)
|
||||||
|
@ -296,7 +376,7 @@ int CDECL _heapadd(void* mem, MSVCRT_size_t size)
|
||||||
*/
|
*/
|
||||||
MSVCRT_intptr_t CDECL _get_heap_handle(void)
|
MSVCRT_intptr_t CDECL _get_heap_handle(void)
|
||||||
{
|
{
|
||||||
return (MSVCRT_intptr_t)GetProcessHeap();
|
return (MSVCRT_intptr_t)heap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
|
@ -304,7 +384,7 @@ MSVCRT_intptr_t CDECL _get_heap_handle(void)
|
||||||
*/
|
*/
|
||||||
MSVCRT_size_t CDECL _msize(void* mem)
|
MSVCRT_size_t CDECL _msize(void* mem)
|
||||||
{
|
{
|
||||||
MSVCRT_size_t size = HeapSize(GetProcessHeap(),0,mem);
|
MSVCRT_size_t size = msvcrt_heap_size(mem);
|
||||||
if (size == ~(MSVCRT_size_t)0)
|
if (size == ~(MSVCRT_size_t)0)
|
||||||
{
|
{
|
||||||
WARN(":Probably called with non wine-allocated memory, ret = -1\n");
|
WARN(":Probably called with non wine-allocated memory, ret = -1\n");
|
||||||
|
@ -318,7 +398,7 @@ MSVCRT_size_t CDECL _msize(void* mem)
|
||||||
*/
|
*/
|
||||||
void* CDECL MSVCRT_calloc(MSVCRT_size_t count, MSVCRT_size_t size)
|
void* CDECL MSVCRT_calloc(MSVCRT_size_t count, MSVCRT_size_t size)
|
||||||
{
|
{
|
||||||
return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, count * size );
|
return msvcrt_heap_alloc(HEAP_ZERO_MEMORY, count*size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
|
@ -327,7 +407,7 @@ void* CDECL MSVCRT_calloc(MSVCRT_size_t count, MSVCRT_size_t size)
|
||||||
void CDECL MSVCRT_free(void* ptr)
|
void CDECL MSVCRT_free(void* ptr)
|
||||||
{
|
{
|
||||||
if(ptr == NULL) return;
|
if(ptr == NULL) return;
|
||||||
HeapFree(GetProcessHeap(),0,ptr);
|
msvcrt_heap_free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
|
@ -335,7 +415,7 @@ void CDECL MSVCRT_free(void* ptr)
|
||||||
*/
|
*/
|
||||||
void* CDECL MSVCRT_malloc(MSVCRT_size_t size)
|
void* CDECL MSVCRT_malloc(MSVCRT_size_t size)
|
||||||
{
|
{
|
||||||
void *ret = HeapAlloc(GetProcessHeap(),0,size);
|
void *ret = msvcrt_heap_alloc(0, size);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
*MSVCRT__errno() = MSVCRT_ENOMEM;
|
*MSVCRT__errno() = MSVCRT_ENOMEM;
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -347,7 +427,7 @@ void* CDECL MSVCRT_malloc(MSVCRT_size_t size)
|
||||||
void* CDECL MSVCRT_realloc(void* ptr, MSVCRT_size_t size)
|
void* CDECL MSVCRT_realloc(void* ptr, MSVCRT_size_t size)
|
||||||
{
|
{
|
||||||
if (!ptr) return MSVCRT_malloc(size);
|
if (!ptr) return MSVCRT_malloc(size);
|
||||||
if (size) return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
|
if (size) return msvcrt_heap_realloc(0, ptr, size);
|
||||||
MSVCRT_free(ptr);
|
MSVCRT_free(ptr);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -373,11 +453,22 @@ MSVCRT_size_t CDECL _get_sbh_threshold(void)
|
||||||
*/
|
*/
|
||||||
int CDECL _set_sbh_threshold(MSVCRT_size_t threshold)
|
int CDECL _set_sbh_threshold(MSVCRT_size_t threshold)
|
||||||
{
|
{
|
||||||
|
#ifdef _WIN64
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
if(threshold > 1016)
|
if(threshold > 1016)
|
||||||
return 0;
|
return 0;
|
||||||
else
|
|
||||||
MSVCRT_sbh_threshold = threshold;
|
if(!sb_heap)
|
||||||
|
{
|
||||||
|
sb_heap = HeapCreate(0, 0, 0);
|
||||||
|
if(!sb_heap)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MSVCRT_sbh_threshold = (threshold+0xf) & ~0xf;
|
||||||
return 1;
|
return 1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
|
@ -635,3 +726,20 @@ int CDECL MSVCRT_strncpy_s(char *dest, MSVCRT_size_t numberOfElements,
|
||||||
dest[0] = '\0';
|
dest[0] = '\0';
|
||||||
return MSVCRT_EINVAL;
|
return MSVCRT_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL msvcrt_init_heap(void)
|
||||||
|
{
|
||||||
|
#ifdef __REACTOS__
|
||||||
|
heap = GetProcessHeap();
|
||||||
|
#else
|
||||||
|
heap = HeapCreate(0, 0, 0);
|
||||||
|
#endif
|
||||||
|
return heap != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void msvcrt_destroy_heap(void)
|
||||||
|
{
|
||||||
|
HeapDestroy(heap);
|
||||||
|
if(sb_heap)
|
||||||
|
HeapDestroy(sb_heap);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue