diff --git a/py/gc.c b/py/gc.c
index b4822ee29fd8e717e91c2db8df9baab7116fe152..a9dd2aa4b0c0c8a13cdf73b565f0bcad2c2de8e1 100644
--- a/py/gc.c
+++ b/py/gc.c
@@ -326,6 +326,7 @@ machine_uint_t gc_nbytes(void *ptr_in) {
     return 0;
 }
 
+#if 0
 // use this realloc for now, one below is broken
 void *gc_realloc(void *ptr, machine_uint_t n_bytes) {
     machine_uint_t n_existing = gc_nbytes(ptr);
@@ -342,8 +343,7 @@ void *gc_realloc(void *ptr, machine_uint_t n_bytes) {
         return ptr2;
     }
 }
-
-#if 0
+#else
 void *gc_realloc(void *ptr_in, machine_uint_t n_bytes) {
     void *ptr_out = NULL;
     machine_uint_t block = 0;
@@ -360,21 +360,22 @@ void *gc_realloc(void *ptr_in, machine_uint_t n_bytes) {
         byte block_type;
         machine_uint_t n_free   = 0;
         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
            the number of free blocks after last tail block */
-        // XXX make sure we stop if we get to end of heap
-        do {
-            block_type = ATB_GET_KIND(block + n_blocks + n_free);
+        /* stop if we reach (or are at) end of heap */
+        while ((block + n_blocks + n_free) < max_block
+                /* 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) {
                 case AT_FREE: n_free++; break;
                 case AT_TAIL: n_blocks++; 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 */
         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 */
-        // XXX disabled for now
-        } else if (0 && n_bytes <= (n_existing + (n_free * BYTES_PER_BLOCK))) {
+        } else if (n_bytes <= (n_existing + (n_free * BYTES_PER_BLOCK))) {
             /* 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)
             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",
                     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++) {
                 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 */
         } 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);
             gc_free(ptr_in);
         }
@@ -413,6 +413,7 @@ void *gc_realloc(void *ptr_in, machine_uint_t n_bytes) {
 
     return ptr_out;
 }
+
 #endif
 
 void gc_dump_info() {