Merge pull request #340 from iabdalkader/realloc

Fix realloc
This commit is contained in:
Damien George 2014-03-12 22:42:33 +00:00
commit df02aaee4f

27
py/gc.c
View File

@ -326,6 +326,7 @@ machine_uint_t gc_nbytes(void *ptr_in) {
return 0; return 0;
} }
#if 0
// use this realloc for now, one below is broken // use this realloc for now, one below is broken
void *gc_realloc(void *ptr, machine_uint_t n_bytes) { void *gc_realloc(void *ptr, machine_uint_t n_bytes) {
machine_uint_t n_existing = gc_nbytes(ptr); machine_uint_t n_existing = gc_nbytes(ptr);
@ -342,8 +343,7 @@ void *gc_realloc(void *ptr, machine_uint_t n_bytes) {
return ptr2; return ptr2;
} }
} }
#else
#if 0
void *gc_realloc(void *ptr_in, machine_uint_t n_bytes) { void *gc_realloc(void *ptr_in, machine_uint_t n_bytes) {
void *ptr_out = NULL; void *ptr_out = NULL;
machine_uint_t block = 0; machine_uint_t block = 0;
@ -360,21 +360,22 @@ void *gc_realloc(void *ptr_in, machine_uint_t n_bytes) {
byte block_type; byte block_type;
machine_uint_t n_free = 0; machine_uint_t n_free = 0;
machine_uint_t n_blocks = 1; /* counting HEAD block */ machine_uint_t n_blocks = 1; /* counting HEAD block */
machine_uint_t max_block = gc_alloc_table_byte_len * BLOCKS_PER_ATB;
/* get the number of consecutive tail blocks and /* get the number of consecutive tail blocks and
the number of free blocks after last tail block */ the number of free blocks after last tail block */
// XXX make sure we stop if we get to end of heap /* stop if we reach (or are at) end of heap */
do { while ((block + n_blocks + n_free) < max_block
block_type = ATB_GET_KIND(block + n_blocks + n_free); /* stop as soon as we find enough blocks for n_bytes */
&& (n_bytes > ((n_blocks+n_free) * BYTES_PER_BLOCK))
/* stop if block is HEAD */
&& (block_type = ATB_GET_KIND(block + n_blocks + n_free)) != AT_HEAD) {
switch (block_type) { switch (block_type) {
case AT_FREE: n_free++; break; case AT_FREE: n_free++; break;
case AT_TAIL: n_blocks++; break; case AT_TAIL: n_blocks++; break;
default: break; default: break;
} }
/* stop as soon as we find enough blocks for n_bytes */ }
// XXX check for n_bytes is wrong since we don't include n_free
} while (block_type != AT_HEAD && (n_bytes > (n_blocks * BYTES_PER_BLOCK)));
/* number of allocated bytes */ /* number of allocated bytes */
machine_uint_t n_existing = n_blocks * BYTES_PER_BLOCK; machine_uint_t n_existing = n_blocks * BYTES_PER_BLOCK;
@ -387,8 +388,7 @@ void *gc_realloc(void *ptr_in, machine_uint_t n_bytes) {
} }
/* check if we can expand in place */ /* check if we can expand in place */
// XXX disabled for now } else if (n_bytes <= (n_existing + (n_free * BYTES_PER_BLOCK))) {
} else if (0 && n_bytes <= (n_existing + (n_free * BYTES_PER_BLOCK))) {
/* number of blocks needed to expand +1 if there's a remainder */ /* number of blocks needed to expand +1 if there's a remainder */
// XXX this has a bug, but don't know why; try: l=[i for i in range(1000)]; for i in l: print(i/3) // XXX this has a bug, but don't know why; try: l=[i for i in range(1000)]; for i in l: print(i/3)
machine_uint_t n_diff = ( n_bytes - n_existing)/BYTES_PER_BLOCK+ machine_uint_t n_diff = ( n_bytes - n_existing)/BYTES_PER_BLOCK+
@ -397,7 +397,7 @@ void *gc_realloc(void *ptr_in, machine_uint_t n_bytes) {
DEBUG_printf("gc_realloc: expanding " UINT_FMT " blocks (" UINT_FMT " bytes) to " UINT_FMT " blocks (" UINT_FMT " bytes)\n", DEBUG_printf("gc_realloc: expanding " UINT_FMT " blocks (" UINT_FMT " bytes) to " UINT_FMT " blocks (" UINT_FMT " bytes)\n",
n_existing/BYTES_PER_BLOCK, n_existing, n_existing/BYTES_PER_BLOCK+n_diff, n_existing + n_diff*BYTES_PER_BLOCK); n_existing/BYTES_PER_BLOCK, n_existing, n_existing/BYTES_PER_BLOCK+n_diff, n_existing + n_diff*BYTES_PER_BLOCK);
/* mark rest of blocks as used tail */ /* mark rest of blocks as used tail */
for (machine_uint_t bl = block + n_blocks; bl < (block + n_blocks + n_diff); bl++) { for (machine_uint_t bl = block + n_blocks; bl < (block + n_blocks + n_diff); bl++) {
ATB_FREE_TO_TAIL(bl); ATB_FREE_TO_TAIL(bl);
} }
@ -405,7 +405,7 @@ void *gc_realloc(void *ptr_in, machine_uint_t n_bytes) {
/* try to find a new contiguous chain */ /* try to find a new contiguous chain */
} else if ((ptr_out = gc_alloc(n_bytes)) != NULL) { } else if ((ptr_out = gc_alloc(n_bytes)) != NULL) {
DEBUG_printf("gc_realloc: allocated new block \n"); DEBUG_printf("gc_realloc: allocating new block \n");
memcpy(ptr_out, ptr_in, n_existing); memcpy(ptr_out, ptr_in, n_existing);
gc_free(ptr_in); gc_free(ptr_in);
} }
@ -413,6 +413,7 @@ void *gc_realloc(void *ptr_in, machine_uint_t n_bytes) {
return ptr_out; return ptr_out;
} }
#endif #endif
void gc_dump_info() { void gc_dump_info() {