Fix large memory chunks allocation with tcg_malloc.
authorKirill Batuzov <batuzovk@ispras.ru>
Fri, 2 Mar 2012 09:22:17 +0000 (13:22 +0400)
committerBlue Swirl <blauwirbel@gmail.com>
Sat, 17 Mar 2012 12:57:48 +0000 (12:57 +0000)
An attempt to allocate a large memory chunk after a small one resulted in
circular links in list of pools.  It caused the same memory being
allocated twice for different arrays.

Now pools for large memory chunks are kept in separate list and are
freed during pool reset because current allocator can not reuse them.

Signed-off-by: Kirill Batuzov <batuzovk@ispras.ru>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
tcg/tcg.c
tcg/tcg.h

index 531db55..ad2e983 100644 (file)
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -173,11 +173,9 @@ void *tcg_malloc_internal(TCGContext *s, int size)
         /* big malloc: insert a new pool (XXX: could optimize) */
         p = g_malloc(sizeof(TCGPool) + size);
         p->size = size;
-        if (s->pool_current)
-            s->pool_current->next = p;
-        else
-            s->pool_first = p;
-        p->next = s->pool_current;
+        p->next = s->pool_first_large;
+        s->pool_first_large = p;
+        return p->data;
     } else {
         p = s->pool_current;
         if (!p) {
@@ -208,6 +206,12 @@ void *tcg_malloc_internal(TCGContext *s, int size)
 
 void tcg_pool_reset(TCGContext *s)
 {
+    TCGPool *p, *t;
+    for (p = s->pool_first_large; p; p = t) {
+        t = p->next;
+        g_free(p);
+    }
+    s->pool_first_large = NULL;
     s->pool_cur = s->pool_end = NULL;
     s->pool_current = NULL;
 }
index cc223ea..92943c1 100644 (file)
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -337,7 +337,7 @@ typedef struct TCGContext TCGContext;
 
 struct TCGContext {
     uint8_t *pool_cur, *pool_end;
-    TCGPool *pool_first, *pool_current;
+    TCGPool *pool_first, *pool_current, *pool_first_large;
     TCGLabel *labels;
     int nb_labels;
     TCGTemp *temps; /* globals first, temps after */