https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c47506a5f4675b4c2248e9874ed32072d787a8bb

commit c47506a5f4675b4c2248e9874ed32072d787a8bb
Author:     Timo Kreuzer <[email protected]>
AuthorDate: Tue Jan 10 10:30:51 2023 +0200
Commit:     Timo Kreuzer <[email protected]>
CommitDate: Tue Jan 24 18:53:13 2023 +0100

    [CRT] Use the original wine heap functions
---
 sdk/lib/crt/misc/crt_init.c |   4 ++
 sdk/lib/crt/wine/heap.c     | 138 +++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 127 insertions(+), 15 deletions(-)

diff --git a/sdk/lib/crt/misc/crt_init.c b/sdk/lib/crt/misc/crt_init.c
index 6818144a8ac..dc0ae5cd94d 100644
--- a/sdk/lib/crt/misc/crt_init.c
+++ b/sdk/lib/crt/misc/crt_init.c
@@ -5,6 +5,7 @@ extern int BlockEnvToEnvironA(void);
 extern int BlockEnvToEnvironW(void);
 extern void FreeEnvironment(char **environment);
 
+extern BOOL msvcrt_init_heap(void);
 extern void msvcrt_init_mt_locks(void);
 extern void msvcrt_init_io(void);
 
@@ -34,6 +35,9 @@ crt_process_init(void)
     if (!msvcrt_init_tls())
         return FALSE;
 
+    if (!msvcrt_init_heap())
+        return FALSE;
+
     if (BlockEnvToEnvironA() < 0)
         return FALSE;
 
diff --git a/sdk/lib/crt/wine/heap.c b/sdk/lib/crt/wine/heap.c
index 8f31f3e30cf..2c3f5ffe260 100644
--- a/sdk/lib/crt/wine/heap.c
+++ b/sdk/lib/crt/wine/heap.c
@@ -56,6 +56,9 @@
     ((((DWORD_PTR)((char *)ptr + alignment + sizeof(void *) + 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);
 
@@ -67,6 +70,78 @@ static unsigned int MSVCRT_amblksiz = 16;
 /* FIXME - According to documentation it should be 480 bytes, at runtime 
default is 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.@)
  */
@@ -78,7 +153,7 @@ void* CDECL MSVCRT_operator_new(MSVCRT_size_t size)
 
   do
   {
-    retval = HeapAlloc(GetProcessHeap(), 0, size);
+    retval = msvcrt_heap_alloc(0, size);
     if(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)
 {
   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)
 {
-  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)
 {
-  if (!HeapValidate( GetProcessHeap(), 0, NULL))
+  if (!HeapValidate(heap, 0, NULL) ||
+          (sb_heap && !HeapValidate(sb_heap, 0, NULL)))
   {
     _dosmaperr(GetLastError());
     return MSVCRT__HEAPBADNODE;
@@ -212,7 +288,8 @@ int CDECL _heapchk(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)
       _dosmaperr(GetLastError());
@@ -228,13 +305,16 @@ int CDECL _heapwalk(struct MSVCRT__heapinfo* next)
 {
   PROCESS_HEAP_ENTRY phe;
 
+  if (sb_heap)
+      FIXME("small blocks heap not supported\n");
+
   LOCK_HEAP;
   phe.lpData = next->_pentry;
   phe.cbData = (DWORD)next->_size;
   phe.wFlags = next->_useflag == MSVCRT__USEDENTRY ? PROCESS_HEAP_ENTRY_BUSY : 
0;
 
   if (phe.lpData && phe.wFlags & PROCESS_HEAP_ENTRY_BUSY &&
-      !HeapValidate( GetProcessHeap(), 0, phe.lpData ))
+      !HeapValidate( heap, 0, phe.lpData ))
   {
     UNLOCK_HEAP;
     _dosmaperr(GetLastError());
@@ -243,7 +323,7 @@ int CDECL _heapwalk(struct MSVCRT__heapinfo* next)
 
   do
   {
-    if (!HeapWalk( GetProcessHeap(), &phe ))
+    if (!HeapWalk( heap, &phe ))
     {
       UNLOCK_HEAP;
       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)
 {
-    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 size = HeapSize(GetProcessHeap(),0,mem);
+  MSVCRT_size_t size = msvcrt_heap_size(mem);
   if (size == ~(MSVCRT_size_t)0)
   {
     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)
 {
-  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)
 {
   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 *ret = HeapAlloc(GetProcessHeap(),0,size);
+  void *ret = msvcrt_heap_alloc(0, size);
   if (!ret)
       *MSVCRT__errno() = MSVCRT_ENOMEM;
   return ret;
@@ -347,7 +427,7 @@ void* CDECL MSVCRT_malloc(MSVCRT_size_t size)
 void* CDECL MSVCRT_realloc(void* ptr, MSVCRT_size_t 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);
   return NULL;
 }
@@ -373,11 +453,22 @@ MSVCRT_size_t CDECL _get_sbh_threshold(void)
  */
 int CDECL _set_sbh_threshold(MSVCRT_size_t threshold)
 {
+#ifdef _WIN64
+  return 0;
+#else
   if(threshold > 1016)
      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;
+#endif
 }
 
 /*********************************************************************
@@ -635,3 +726,20 @@ int CDECL MSVCRT_strncpy_s(char *dest, MSVCRT_size_t 
numberOfElements,
     dest[0] = '\0';
     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);
+}

Reply via email to