Introduce dynamic heap management

* heap size doubles every time we are running out of space after a GC
* allocations when the heap is too filled are done with regular malloc,
  and promptly freed after as we request a GC.
* improves the memory footprint and does not increase execution time.