[evolution-patches] Re: [patch] another 64-bit bug-fix



The patch below fixes more 64-bit problems, this time in camel-mime-parser.c.

The problem there is two-fold:

 (1) STRUCT_ALIGN is set to only 4.  This implies that on 64-bit
     machines, we may end up with misaligned pointers, which is slow
     on many RISC-type architectures and also on ia64.  The fix is to
     change the alignment to sizeof (void *).

 (2) Even with STRUCT_ALIGN set to sizeof (void *), we may still end
     up with misaligned pointers because the code doesn't take into account
     struct alignment.  To fix this, I removed the "data[1]" members from
     MemPoolNode/MemPoolThresholdNode structures and used pointer-arithmetic
     to calculate the starting address of the data portion.

With these changes, there are no misaligned accesses anymore.

Thanks,

	--david

PS: I developed the patch for evolution v2.0.3, but the code in question
    appears mostly unchanged in CVS and I verified that the patch applies
    cleanly against the CVS version.

--- camel-mime-parser.c~	2004-12-05 23:46:50.000000000 -0800
+++ camel-mime-parser.c	2004-12-14 22:23:14.142731476 -0800
@@ -57,7 +57,7 @@
 
 #define MEMPOOL
 
-#define STRUCT_ALIGN 4
+#define STRUCT_ALIGN (sizeof (void *))
 
 #ifdef PURIFY
 int inend_id = -1,
@@ -76,12 +76,10 @@
 	struct _MemPoolNode *next;
 
 	int free;
-	char data[1];
 } MemPoolNode;
 
 typedef struct _MemPoolThresholdNode {
 	struct _MemPoolThresholdNode *next;
-	char data[1];
 } MemPoolThresholdNode;
 
 typedef struct _MemPool {
@@ -116,10 +114,10 @@
 	if (size>=pool->threshold) {
 		MemPoolThresholdNode *n;
 
-		n = g_malloc(sizeof(*n) - sizeof(char) + size);
+		n = g_malloc(sizeof(*n) + size);
 		n->next = pool->threshold_blocks;
 		pool->threshold_blocks = n;
-		return &n->data[0];
+		return n + 1;
 	} else {
 		MemPoolNode *n;
 
@@ -127,16 +125,16 @@
 		while (n) {
 			if (n->free >= size) {
 				n->free -= size;
-				return &n->data[n->free];
+				return (char *) (n + 1) + n->free;
 			}
 			n = n->next;
 		}
 
-		n = g_malloc(sizeof(*n) - sizeof(char) + pool->blocksize);
+		n = g_malloc(sizeof(*n) + pool->blocksize);
 		n->next = pool->blocks;
 		pool->blocks = n;
 		n->free = pool->blocksize - size;
-		return &n->data[n->free];
+		return (char *) (n + 1) + n->free;
 	}
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]