cvs: ZendEngine2 / zend_mm.c zend_mm.h
| From: | Andi Gutmans | Date: | Mon, 09 Dec 2002 08:14:01 +0000 |
| Subject: | cvs: ZendEngine2 / zend_mm.c zend_mm.h | ||
| Groups: | php.zend-engine.cvs | ||
| Request: | Send a blank email to php-zend-engine-cvs+get-698@lists.php.net to get a copy of this message | ||
andi Mon Dec 9 03:14:01 2002 EDT
Modified files:
/ZendEngine2 zend_mm.c zend_mm.h
Log:
- First attempt to improve memory manager during realloc()'s
Index: ZendEngine2/zend_mm.c
diff -u ZendEngine2/zend_mm.c:1.14 ZendEngine2/zend_mm.c:1.15
--- ZendEngine2/zend_mm.c:1.14 Wed Aug 7 10:47:41 2002
+++ ZendEngine2/zend_mm.c Mon Dec 9 03:14:00 2002
@@ -57,6 +57,7 @@
#define ZEND_MM_ALIGNED_FREE_HEADER_SIZE ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_free_block))
#define ZEND_MM_ALIGNED_SEGMENT_SIZE ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_segment))
+#define ZEND_MM_ALIGNED_MAX_HEADER_SIZE MAX(ZEND_MM_ALIGNED_HEADER_SIZE,
ZEND_MM_ALIGNED_FREE_HEADER_SIZE)
/* Memory calculations */
#define ZEND_MM_BLOCK_AT(blk, offset) ((zend_mm_block *) (((char *) (blk))+(offset)))
@@ -152,14 +153,15 @@
block_size -= ZEND_MM_ALIGNED_SEGMENT_SIZE;
mm_block = (zend_mm_free_block *) ((char *) segment + ZEND_MM_ALIGNED_SEGMENT_SIZE);
- mm_block->size = block_size - ZEND_MM_ALIGNED_FREE_HEADER_SIZE; /* keep one guard block in the
end */
+ mm_block->size = block_size - ZEND_MM_ALIGNED_HEADER_SIZE; /* keep one guard block in the end
*/
mm_block->type = ZEND_MM_FREE_BLOCK;
mm_block->prev_size = 0; /* Size is always at least ZEND_MM_ALIGNED_HEADER_SIZE big (>0) so
0 is OK */
/* setup guard block */
guard_block = ZEND_MM_BLOCK_AT(mm_block, mm_block->size);
guard_block->type = ZEND_MM_USED_BLOCK;
- guard_block->size = ZEND_MM_ALIGNED_FREE_HEADER_SIZE;
+ guard_block->size = ZEND_MM_ALIGNED_HEADER_SIZE;
+ guard_block->guard_block = 1;
guard_block->prev_size = mm_block->size;
ZEND_MM_DEBUG(("Setup guard block at 0x%0.8X\n", guard_block));
@@ -231,9 +233,9 @@
zend_mm_finished_searching_for_block:
if (!best_fit) {
- if (true_size > (heap->block_size - ZEND_MM_ALIGNED_SEGMENT_SIZE -
ZEND_MM_ALIGNED_FREE_HEADER_SIZE)) {
+ if (true_size > (heap->block_size - ZEND_MM_ALIGNED_SEGMENT_SIZE -
ZEND_MM_ALIGNED_HEADER_SIZE)) {
/* Make sure we add a memory block which is big enough */
- zend_mm_add_memory_block(heap, true_size + ZEND_MM_ALIGNED_SEGMENT_SIZE +
ZEND_MM_ALIGNED_FREE_HEADER_SIZE);
+ zend_mm_add_memory_block(heap, true_size + ZEND_MM_ALIGNED_SEGMENT_SIZE +
ZEND_MM_ALIGNED_HEADER_SIZE);
} else {
zend_mm_add_memory_block(heap, heap->block_size);
}
@@ -242,6 +244,7 @@
/* mark as used */
best_fit->type = ZEND_MM_USED_BLOCK;
+ ((zend_mm_block *) best_fit)->guard_block = 0;
/* remove from free list */
zend_mm_remove_from_free_list(heap, best_fit);
@@ -257,7 +260,7 @@
zend_mm_block *mm_block = ZEND_MM_HEADER_OF(p);
zend_mm_block *prev_block, *next_block;
- if (mm_block->type!=ZEND_MM_USED_BLOCK) {
+ if (mm_block->type != ZEND_MM_USED_BLOCK) {
/* error */
return;
}
@@ -299,6 +302,34 @@
}
next_block = ZEND_MM_BLOCK_AT(mm_block, mm_block->size);
+
+ if ((mm_block->prev_size == 0) && (next_block->type == ZEND_MM_USED_BLOCK)
&&
+ (next_block->guard_block)) {
+ zend_mm_segment *segment = (zend_mm_segment *) ((char *)mm_block - ZEND_MM_ALIGNED_SEGMENT_SIZE);
+ zend_mm_segment *segment_copy = segment;
+ zend_mm_block *guard_block;
+ size_t realloc_to_size;
+
+ /* segment size, size of block and size of guard block */
+ realloc_to_size = ZEND_MM_ALIGNED_SEGMENT_SIZE+true_size+ZEND_MM_ALIGNED_HEADER_SIZE;
+ segment = realloc(segment, realloc_to_size);
+ if (segment != segment_copy) {
+ /* The segment moved. Fix the segment list */
+ fprintf(stderr, "Segment moved! This is not handled right now\n");
+ exit(1);
+ }
+
+ mm_block->size = true_size;
+
+ /* setup guard block */
+ guard_block = ZEND_MM_BLOCK_AT(mm_block, mm_block->size);
+ guard_block->type = ZEND_MM_USED_BLOCK;
+ guard_block->size = ZEND_MM_ALIGNED_HEADER_SIZE;
+ guard_block->guard_block = 1;
+ guard_block->prev_size = mm_block->size;
+
+ return ZEND_MM_DATA_OF(mm_block);
+ }
if (next_block->type != ZEND_MM_FREE_BLOCK || (mm_block->size + next_block->size <
true_size)) {
void *ptr;
Index: ZendEngine2/zend_mm.h
diff -u ZendEngine2/zend_mm.h:1.8 ZendEngine2/zend_mm.h:1.9
--- ZendEngine2/zend_mm.h:1.8 Wed Jun 26 10:24:23 2002
+++ ZendEngine2/zend_mm.h Mon Dec 9 03:14:00 2002
@@ -32,6 +32,7 @@
unsigned int size : 31;
unsigned int type : 1;
size_t prev_size;
+ unsigned int guard_block : 1;
} zend_mm_block;
typedef struct _zend_mm_free_block {