123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- #include <assert.h>
- #include "private.h"
- #include "context.h"
- #include "node.h"
- /*--------------------------------------------------------- */
- static void
- lub_heap_free_leading_memory(lub_heap_t *this,
- lub_heap_block_t *block,
- size_t size)
- {
- lub_heap_block_t *prev_block = lub_heap_block_getprevious(block);
- if(prev_block && prev_block->free.tag.free)
- {
- /*
- * add the excess bytes to a preceeding free block
- */
- lub_heap_graft_to_top(this,
- prev_block,
- block,
- (size >> 2),
- BOOL_FALSE,
- BOOL_FALSE);
- }
- else
- {
- /*
- * convert the excess bytes into a free block
- */
- lub_heap_init_free_block(this,
- block,
- size,
- block->alloc.tag.segment,
- BOOL_FALSE);
- }
- this->stats.alloc_bytes -= size;
- }
- /*--------------------------------------------------------- */
- static void
- lub_heap_free_trailing_memory(lub_heap_t *this,
- lub_heap_block_t *block,
- size_t size)
- {
- bool_t done = BOOL_FALSE;
- lub_heap_block_t *next_block = lub_heap_block_getnext(block);
- lub_heap_tag_t *tail = lub_heap_block__get_tail(block);
- char *ptr = (char*)&tail[1] - size;
- if(next_block && next_block->free.tag.free)
- {
- /*
- * try and add the excess bytes to a following free block
- */
- lub_heap_graft_to_bottom(this,
- next_block,
- ptr,
- (size >> 2),
- BOOL_FALSE,
- BOOL_FALSE);
- done = BOOL_TRUE;
- }
- else if(size >= sizeof(lub_heap_free_block_t))
- {
- /*
- * convert the excess bytes into a free block
- */
- lub_heap_init_free_block(this,
- ptr,
- size,
- BOOL_FALSE,
- tail->segment);
- done = BOOL_TRUE;
- }
- if(done)
- {
- /* correct the word count for the block */
- block->alloc.tag.words -= (size >> 2);
- tail = lub_heap_block__get_tail(block);
- tail->segment = 0;
- tail->free = 0;
- tail->words = block->alloc.tag.words;
- this->stats.alloc_bytes -= size;
- }
- }
- /*--------------------------------------------------------- */
- void
- lub_heap_align_block(lub_heap_t *this,
- lub_heap_align_t alignment,
- char **ptr,
- size_t *size)
- {
- if(*ptr)
- {
- lub_heap_block_t *block = lub_heap_block_from_ptr(*ptr);
- lub_heap_block_t *new_block;
- lub_heap_tag_t *new_tail;
- /* find the second occurance of an alignment boundary */
- size_t tmp = (alignment-1);
- char *new_ptr = (char *)(((size_t)*ptr + tmp + alignment) & ~tmp);
- size_t leading_bytes = (new_ptr - *ptr);
- size_t trailing_bytes;
-
- /* check this is a allocated block */
- assert(0 == block->alloc.tag.free);
- /*
- * We MUST have left sufficient space to fit a free block and
- * leak dection node if necessary.
- */
- assert(leading_bytes >= (sizeof(lub_heap_free_block_t) + sizeof(lub_heap_node_t)));
- if((0 < lub_heap_frame_count) && (0 == this->suppress))
- {
- /*
- * If leak detection is enabled then offset the pointer back by the size of
- * a lub_heap_node; which will be filled out by lub_heap_post_realloc()
- */
- new_ptr -= sizeof(lub_heap_node_t);
- leading_bytes -= sizeof(lub_heap_node_t);
- }
- /*
- * Create a new header just before the new pointer
- */
- new_block = lub_heap_block_from_ptr(new_ptr);
- new_block->alloc.tag.free = 0;
- new_block->alloc.tag.segment = 0;
- new_block->alloc.tag.words = block->alloc.tag.words - (leading_bytes >> 2);
- /* fix the size in the tail */
- new_tail = lub_heap_block__get_tail(new_block);
- new_tail->words = new_block->alloc.tag.words;
- lub_heap_free_leading_memory(this,
- block,
- leading_bytes);
- /* identify any trailing excess memory */
- trailing_bytes = (new_block->alloc.tag.words << 2) - (*size - (alignment << 1));
-
- if(trailing_bytes)
- {
- lub_heap_free_trailing_memory(this,
- new_block,
- trailing_bytes);
- }
- *size = (new_block->alloc.tag.words << 2); /* size including the lub_heap_alloc_block_t details */
- *ptr = new_ptr;
- }
- }
|