changeset 941:4d6b69558add HEAD

Added old_size parameter to p_realloc() - we rarely need it and this way each allocation takes 8 bytes less memory.
author Timo Sirainen <tss@iki.fi>
date Fri, 10 Jan 2003 22:58:28 +0200
parents 65639e7a7cb0
children fbd907ad9b27
files src/lib-imap/imap-parser.c src/lib/buffer.c src/lib/hash.c src/lib/hash.h src/lib/imem.c src/lib/imem.h src/lib/ioloop-poll.c src/lib/istream-file.c src/lib/mempool-alloconly.c src/lib/mempool-datastack.c src/lib/mempool-system.c src/lib/mempool.h src/lib/ostream-file.c
diffstat 13 files changed, 92 insertions(+), 139 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-imap/imap-parser.c	Fri Jan 10 15:36:01 2003 +0200
+++ b/src/lib-imap/imap-parser.c	Fri Jan 10 22:58:28 2003 +0200
@@ -46,14 +46,16 @@
 	unsigned int eol:1;
 };
 
-#define LIST_REALLOC(parser, old_list, size) \
+/* @UNSAFE */
+#define LIST_REALLOC(parser, old_list, new_size) \
 	p_realloc((parser)->pool, old_list, \
 		  sizeof(struct imap_arg_list) + \
-		  sizeof(struct imap_arg) * ((size)-1))
+		  (old_list == NULL ? 0 : \
+		   sizeof(struct imap_arg) * (old_list)->alloc), \
+		  sizeof(struct imap_arg) * (new_size))
 
 static void imap_args_realloc(struct imap_parser *parser, size_t size)
 {
-	/* @UNSAFE */
 	parser->cur_list = LIST_REALLOC(parser, parser->cur_list, size);
 	parser->cur_list->alloc = size;
 
@@ -536,10 +538,10 @@
 		   that last argument isn't only partially parsed. */
 		if (count >= parser->root_list->alloc) {
 			/* unused arguments must be NIL-filled. */
-			parser->root_list->alloc = count+1;
 			parser->root_list = LIST_REALLOC(parser,
 							 parser->root_list,
 							 count+1);
+			parser->root_list->alloc = count+1;
 		}
 
 		parser->root_list->args[parser->root_list->size].type =
--- a/src/lib/buffer.c	Fri Jan 10 15:36:01 2003 +0200
+++ b/src/lib/buffer.c	Fri Jan 10 22:58:28 2003 +0200
@@ -54,11 +54,9 @@
 
 	i_assert(size > buf->alloc);
 
+	buf->w_buffer = p_realloc(buf->pool, buf->w_buffer, buf->alloc, size);
 	buf->alloc = size;
-	if (buf->w_buffer == NULL)
-		buf->w_buffer = p_malloc(buf->pool, buf->alloc);
-	else
-		buf->w_buffer = p_realloc(buf->pool, buf->w_buffer, buf->alloc);
+
 	buf->r_buffer = buf->w_buffer;
 	buf->alloced = TRUE;
 }
--- a/src/lib/hash.c	Fri Jan 10 15:36:01 2003 +0200
+++ b/src/lib/hash.c	Fri Jan 10 22:58:28 2003 +0200
@@ -88,8 +88,8 @@
 	}
 }
 
-struct hash_table *hash_create(pool_t pool, unsigned int initial_size,
-			       HashFunc hash_func,
+struct hash_table *hash_create(pool_t node_pool, pool_t table_pool,
+			       unsigned int initial_size, HashFunc hash_func,
 			       HashCompareFunc key_compare_func)
 {
 	struct hash_table *table;
@@ -97,7 +97,8 @@
         i_assert(pool != NULL);
 
 	table = p_new(pool, struct hash_table, 1);
-        table->pool = pool;
+        table->node_pool = node_pool;
+        table->table_pool = table_pool;
 	table->size = CLAMP(primes_closest(initial_size),
 			    HASH_TABLE_MIN_SIZE,
 			    HASH_TABLE_MAX_SIZE);
--- a/src/lib/hash.h	Fri Jan 10 15:36:01 2003 +0200
+++ b/src/lib/hash.h	Fri Jan 10 22:58:28 2003 +0200
@@ -10,8 +10,8 @@
 /* Create a new hash table. If initial_size is 0, the default value is used.
    If hash_func or key_compare_func is NULL, direct hashing/comparing
    is used. */
-struct hash_table *hash_create(pool_t pool, unsigned int initial_size,
-			       HashFunc hash_func,
+struct hash_table *hash_create(pool_t node_pool, pool_t hash_pool,
+			       unsigned int initial_size, HashFunc hash_func,
 			       HashCompareFunc key_compare_func);
 void hash_destroy(struct hash_table *table);
 
--- a/src/lib/imem.c	Fri Jan 10 15:36:01 2003 +0200
+++ b/src/lib/imem.c	Fri Jan 10 22:58:28 2003 +0200
@@ -37,9 +37,9 @@
         p_free(default_pool, mem);
 }
 
-void *i_realloc(void *mem, size_t size)
+void *i_realloc(void *mem, size_t old_size, size_t new_size)
 {
-        return p_realloc(default_pool, mem, size);
+        return p_realloc(default_pool, mem, old_size, new_size);
 }
 
 char *i_strdup(const char *str)
--- a/src/lib/imem.h	Fri Jan 10 15:36:01 2003 +0200
+++ b/src/lib/imem.h	Fri Jan 10 22:58:28 2003 +0200
@@ -8,7 +8,7 @@
         ((type *) i_malloc(sizeof(type) * (count)))
 void *i_malloc(size_t size);
 void i_free(void *mem);
-void *i_realloc(void *mem, size_t size);
+void *i_realloc(void *mem, size_t old_size, size_t new_size);
 
 /* string functions */
 char *i_strdup(const char *str);
--- a/src/lib/ioloop-poll.c	Fri Jan 10 15:36:01 2003 +0200
+++ b/src/lib/ioloop-poll.c	Fri Jan 10 22:58:28 2003 +0200
@@ -71,7 +71,8 @@
 void io_loop_handle_add(struct ioloop *ioloop, int fd, int condition)
 {
 	struct ioloop_handler_data *data = ioloop->handler_data;
-	int index, old_size;
+	unsigned int old_size;
+	int index;
 
 	if ((unsigned int) fd >= data->idx_size) {
                 /* grow the fd -> index array */
@@ -79,6 +80,7 @@
 
 		data->idx_size = nearest_power((unsigned int) fd+1);
 		data->fd_index = p_realloc(ioloop->pool, data->fd_index,
+					   sizeof(int) * old_size,
 					   sizeof(int) * data->idx_size);
 		memset(data->fd_index + old_size, 0xff,
 		       sizeof(int) * (data->idx_size-old_size));
@@ -86,8 +88,11 @@
 
 	if (data->fds_pos >= data->fds_size) {
 		/* grow the fd array */
+		old_size = data->fds_size;
+
 		data->fds_size = nearest_power(data->fds_size+1);
 		data->fds = p_realloc(ioloop->pool, data->fds,
+				      sizeof(struct pollfd) * old_size,
 				      sizeof(struct pollfd) * data->fds_size);
 	}
 
--- a/src/lib/istream-file.c	Fri Jan 10 15:36:01 2003 +0200
+++ b/src/lib/istream-file.c	Fri Jan 10 22:58:28 2003 +0200
@@ -97,11 +97,15 @@
 static void i_stream_grow_buffer(struct _istream *stream, size_t bytes)
 {
 	struct file_istream *fstream = (struct file_istream *) stream;
+	size_t old_size;
+
+	old_size = stream->buffer_size;
 
 	stream->buffer_size = stream->pos + bytes;
-	stream->buffer_size =
-		stream->buffer_size <= I_STREAM_MIN_SIZE ? I_STREAM_MIN_SIZE :
-		nearest_power(stream->buffer_size);
+	if (stream->buffer_size <= I_STREAM_MIN_SIZE)
+		stream->buffer_size = I_STREAM_MIN_SIZE;
+	else
+		stream->buffer_size = nearest_power(stream->buffer_size);
 
 	if (fstream->max_buffer_size > 0 &&
 	    stream->buffer_size > fstream->max_buffer_size)
@@ -109,7 +113,7 @@
 
 	stream->buffer = stream->w_buffer =
 		p_realloc(stream->iostream.pool, stream->w_buffer,
-			  stream->buffer_size);
+			  old_size, stream->buffer_size);
 }
 
 static void i_stream_compress(struct _istream *stream)
--- a/src/lib/mempool-alloconly.c	Fri Jan 10 15:36:01 2003 +0200
+++ b/src/lib/mempool-alloconly.c	Fri Jan 10 22:58:28 2003 +0200
@@ -57,20 +57,12 @@
 #define POOL_BLOCK_DATA(block) \
 	((char *) (block) + SIZEOF_POOLBLOCK)
 
-struct pool_alloc {
-	union {
-		size_t size;
-		unsigned char alignment[MEM_ALIGN_SIZE];
-	} size;
-	unsigned char data[MEM_ALIGN_SIZE]; /* variable size */
-};
-#define SIZEOF_POOLALLOC (sizeof(struct pool_alloc)-MEM_ALIGN_SIZE)
-
 static void pool_alloconly_ref(pool_t pool);
 static void pool_alloconly_unref(pool_t pool);
 static void *pool_alloconly_malloc(pool_t pool, size_t size);
 static void pool_alloconly_free(pool_t pool, void *mem);
-static void *pool_alloconly_realloc(pool_t pool, void *mem, size_t size);
+static void *pool_alloconly_realloc(pool_t pool, void *mem,
+				    size_t old_size, size_t new_size);
 static void pool_alloconly_clear(pool_t pool);
 
 static void block_alloc(struct alloconly_pool *pool, size_t size);
@@ -160,25 +152,24 @@
 static void *pool_alloconly_malloc(pool_t pool, size_t size)
 {
 	struct alloconly_pool *apool = (struct alloconly_pool *) pool;
-	struct pool_alloc *alloc;
+	void *mem;
 
 	if (size == 0 || size > SSIZE_T_MAX)
 		i_panic("Trying to allocate %"PRIuSIZE_T" bytes", size);
 
 	size = MEM_ALIGN(size);
 
-	if (apool->block->left < size + SIZEOF_POOLALLOC) {
+	if (apool->block->left < size) {
 		/* we need a new block */
 		block_alloc(apool, size);
 	}
 
-	alloc = (struct pool_alloc *) (POOL_BLOCK_DATA(apool->block) +
-				       apool->block->size - apool->block->left);
-	alloc->size.size = size;
+	mem = POOL_BLOCK_DATA(apool->block) +
+		(apool->block->size - apool->block->left);
 
-	apool->block->left -= size + SIZEOF_POOLALLOC;
+	apool->block->left -= size;
 	apool->block->last_alloc_size = size;
-	return alloc->data;
+	return mem;
 }
 
 static void pool_alloconly_free(pool_t pool __attr_unused__,
@@ -206,39 +197,34 @@
 	return FALSE;
 }
 
-static void *pool_alloconly_realloc(pool_t pool, void *mem, size_t size)
+static void *pool_alloconly_realloc(pool_t pool, void *mem,
+				    size_t old_size, size_t new_size)
 {
 	struct alloconly_pool *apool = (struct alloconly_pool *) pool;
-	struct pool_alloc *alloc;
 	unsigned char *new_mem;
-	size_t old_size;
 
-	if (size == 0 || size > SSIZE_T_MAX)
-		i_panic("Trying to allocate %"PRIuSIZE_T" bytes", size);
+	if (new_size == 0 || new_size > SSIZE_T_MAX)
+		i_panic("Trying to allocate %"PRIuSIZE_T" bytes", new_size);
 
 	if (mem == NULL)
-		return pool_alloconly_malloc(pool, size);
+		return pool_alloconly_malloc(pool, new_size);
 
-	/* get old size */
-	alloc = (struct pool_alloc *) ((char *) mem - SIZEOF_POOLALLOC);
-	old_size = alloc->size.size;
-
-	if (size <= old_size)
+	if (new_size <= old_size)
 		return mem;
 
-	size = MEM_ALIGN(size);
+	new_size = MEM_ALIGN(new_size);
 
 	/* see if we can directly grow it */
-	if (!pool_try_grow(apool, mem, size)) {
+	if (!pool_try_grow(apool, mem, new_size)) {
 		/* slow way - allocate + copy */
-		new_mem = pool_alloconly_malloc(pool, size);
+		new_mem = pool_alloconly_malloc(pool, new_size);
 		memcpy(new_mem, mem, old_size);
 		mem = new_mem;
 	}
 
-	if (size > old_size) {
+	if (old_size < new_size) {
                 /* clear new data */
-		memset((char *) mem + old_size, 0, size - old_size);
+		memset((char *) mem + old_size, 0, new_size - old_size);
 	}
 
         return mem;
--- a/src/lib/mempool-datastack.c	Fri Jan 10 15:36:01 2003 +0200
+++ b/src/lib/mempool-datastack.c	Fri Jan 10 22:58:28 2003 +0200
@@ -28,19 +28,12 @@
 
 #include <stdlib.h>
 
-struct pool_alloc {
-	union {
-		size_t size;
-		unsigned char alignment[MEM_ALIGN_SIZE];
-	} size;
-	/* void data[]; */
-};
-
 static void pool_data_stack_ref(pool_t pool);
 static void pool_data_stack_unref(pool_t pool);
 static void *pool_data_stack_malloc(pool_t pool, size_t size);
 static void pool_data_stack_free(pool_t pool, void *mem);
-static void *pool_data_stack_realloc(pool_t pool, void *mem, size_t size);
+static void *pool_data_stack_realloc(pool_t pool, void *mem,
+				     size_t old_size, size_t new_size);
 static void pool_data_stack_clear(pool_t pool);
 
 static struct pool static_data_stack_pool = {
@@ -67,15 +60,10 @@
 
 static void *pool_data_stack_malloc(pool_t pool __attr_unused__, size_t size)
 {
-	struct pool_alloc *alloc;
-
 	if (size == 0 || size > SSIZE_T_MAX)
 		i_panic("Trying to allocate %"PRIuSIZE_T" bytes", size);
 
-	alloc = t_malloc0(sizeof(struct pool_alloc) + size);
-	alloc->size.size = size;
-
-	return (char *) alloc + sizeof(struct pool_alloc);
+	return t_malloc0(size);
 }
 
 static void pool_data_stack_free(pool_t pool __attr_unused__,
@@ -83,38 +71,29 @@
 {
 }
 
-static void *pool_data_stack_realloc(pool_t pool __attr_unused__,
-				     void *mem, size_t size)
+static void *pool_data_stack_realloc(pool_t pool __attr_unused__, void *mem,
+				     size_t old_size, size_t new_size)
 {
+	void *new_mem;
+
 	/* @UNSAFE */
-	struct pool_alloc *alloc, *new_alloc;
-        size_t old_size;
-	unsigned char *rmem;
-
-	if (size == 0 || size > SSIZE_T_MAX)
-		i_panic("Trying to allocate %"PRIuSIZE_T" bytes", size);
+	if (new_size == 0 || new_size > SSIZE_T_MAX)
+		i_panic("Trying to allocate %"PRIuSIZE_T" bytes", new_size);
 
 	if (mem == NULL)
-		return pool_data_stack_malloc(pool, size);
+		return pool_data_stack_malloc(pool, new_size);
 
-	/* get old size */
-	alloc = (struct pool_alloc *)
-		((char *) mem - sizeof(struct pool_alloc));
-	old_size = alloc->size.size;
-
-	if (old_size >= size)
+	if (old_size >= new_size)
 		return mem;
 
-	if (!t_try_realloc(alloc, sizeof(struct pool_alloc) + size)) {
-		new_alloc = t_malloc(sizeof(struct pool_alloc) + size);
-		memcpy(new_alloc, alloc, old_size + sizeof(struct pool_alloc));
-		alloc = new_alloc;
+	if (!t_try_realloc(mem, new_size)) {
+		new_mem = t_malloc(new_size);
+		memcpy(new_mem, mem, old_size);
+		mem = new_mem;
 	}
-	alloc->size.size = size;
 
-        rmem = (unsigned char *) alloc + sizeof(struct pool_alloc);
-	memset(rmem + old_size, 0, size-old_size);
-	return rmem;
+	memset((char *) mem + old_size, 0, new_size - old_size);
+	return mem;
 }
 
 static void pool_data_stack_clear(pool_t pool __attr_unused__)
--- a/src/lib/mempool-system.c	Fri Jan 10 15:36:01 2003 +0200
+++ b/src/lib/mempool-system.c	Fri Jan 10 22:58:28 2003 +0200
@@ -30,19 +30,12 @@
 
 #include <stdlib.h>
 
-struct pool_alloc {
-	union {
-		size_t size;
-		unsigned char alignment[MEM_ALIGN_SIZE];
-	} size;
-	/* void data[]; */
-};
-
 static void pool_system_ref(pool_t pool);
 static void pool_system_unref(pool_t pool);
 static void *pool_system_malloc(pool_t pool, size_t size);
 static void pool_system_free(pool_t pool, void *mem);
-static void *pool_system_realloc(pool_t pool, void *mem, size_t size);
+static void *pool_system_realloc(pool_t pool, void *mem,
+				 size_t old_size, size_t new_size);
 static void pool_system_clear(pool_t pool);
 
 static struct pool static_system_pool = {
@@ -69,58 +62,40 @@
 
 static void *pool_system_malloc(pool_t pool __attr_unused__, size_t size)
 {
-	struct pool_alloc *alloc;
+	void *mem;
 
 	if (size == 0 || size > SSIZE_T_MAX)
 		i_panic("Trying to allocate %"PRIuSIZE_T" bytes", size);
 
-	alloc = calloc(sizeof(struct pool_alloc) + size, 1);
-	if (alloc == NULL)
+	mem = calloc(size, 1);
+	if (mem == NULL)
 		i_panic("pool_system_malloc(): Out of memory");
-	alloc->size.size = size;
 
-	return (char *) alloc + sizeof(struct pool_alloc);
+	return mem;
 }
 
 static void pool_system_free(pool_t pool __attr_unused__, void *mem)
 {
 	if (mem != NULL)
-		free((char *) mem - sizeof(struct pool_alloc));
+		free(mem);
 }
 
 static void *pool_system_realloc(pool_t pool __attr_unused__, void *mem,
-				 size_t size)
+				 size_t old_size, size_t new_size)
 {
-	struct pool_alloc *alloc;
-	size_t old_size;
-	char *rmem;
-
-	if (size == 0 || size > SSIZE_T_MAX)
-		i_panic("Trying to allocate %"PRIuSIZE_T" bytes", size);
+	if (new_size == 0 || new_size > SSIZE_T_MAX)
+		i_panic("Trying to allocate %"PRIuSIZE_T" bytes", new_size);
 
-	if (mem == NULL) {
-		alloc = NULL;
-		old_size = 0;
-	} else {
-		/* get old size */
-		alloc = (struct pool_alloc *)
-			((char *) mem - sizeof(struct pool_alloc));
-		old_size = alloc->size.size;
+	mem = realloc(mem, new_size);
+	if (mem == NULL)
+		i_panic("pool_system_realloc(): Out of memory");
+
+	if (old_size < new_size) {
+                /* clear new data */
+		memset(mem + old_size, 0, new_size - old_size);
 	}
 
-        /* alloc & set new size */
-	alloc = realloc(alloc, sizeof(struct pool_alloc) + size);
-	if (alloc == NULL)
-		i_panic("pool_system_realloc(): Out of memory");
-	alloc->size.size = size;
-
-        rmem = (char *) alloc + sizeof(struct pool_alloc);
-	if (size > old_size) {
-                /* clear new data */
-		memset(rmem + old_size, 0, size-old_size);
-	}
-
-        return rmem;
+        return mem;
 }
 
 static void pool_system_clear(pool_t pool __attr_unused__)
--- a/src/lib/mempool.h	Fri Jan 10 15:36:01 2003 +0200
+++ b/src/lib/mempool.h	Fri Jan 10 22:58:28 2003 +0200
@@ -18,8 +18,9 @@
 	void *(*malloc)(pool_t pool, size_t size);
 	void (*free)(pool_t pool, void *mem);
 
-	/* reallocate the `mem' to be exactly `size' */
-	void *(*realloc)(pool_t pool, void *mem, size_t size);
+	/* memory in old_size..new_size will be zeroed */
+	void *(*realloc)(pool_t pool, void *mem,
+			 size_t old_size, size_t new_size);
 
 	/* Frees all the memory in pool. NOTE: system_pool doesn't support
 	   this and crashes if it's used */
@@ -41,7 +42,8 @@
 #define pool_unref(pool) (pool)->unref(pool)
 
 #define p_malloc(pool, size) (pool)->malloc(pool, size)
-#define p_realloc(pool, mem, size) (pool)->realloc(pool, mem, size)
+#define p_realloc(pool, mem, old_size, new_size) \
+	(pool)->realloc(pool, mem, old_size, new_size)
 #define p_free(pool, mem) (pool)->free(pool, mem)
 
 #define p_clear(pool) (pool)->clear(pool)
--- a/src/lib/ostream-file.c	Fri Jan 10 15:36:01 2003 +0200
+++ b/src/lib/ostream-file.c	Fri Jan 10 22:58:28 2003 +0200
@@ -389,7 +389,8 @@
 		return;
 
 	fstream->buffer = p_realloc(fstream->ostream.iostream.pool,
-				    fstream->buffer, size);
+				    fstream->buffer,
+				    fstream->buffer_size, size);
 
 	if (fstream->tail <= fstream->head && !IS_STREAM_EMPTY(fstream)) {
 		head_size = I_MIN(fstream->head, size - fstream->buffer_size);