Introduce dynamic heap management

* heapSize doubles every time we are running out of space after a GC
  or allocated a too big chunk (>= 5%) outside of the _baseBlock.
* allocations when the heap is too filled are done with regular malloc,
  and promptly freed after as we request a GC and grow the size
  to fit the extra alloc (so it should not happen anymore for that block).
* improves the memory footprint and does not increase execution time.
* _maxMemory is kept as an upper bound of memory usage (not yet implemented).