т.е. я бы сделал алгоритм инстанцирования памяти нового модуля примерно так:
1. Выставляем heap_base равный memory.size (считаем, что если других модулей нет, то memory.size вернёт __data_end).
2. Аллокатор модуля инициализируется и сам сдвигает memory_limit на N (параметр аллокатора) страниц
Далее если места не хватает, то аллокатор берёт запоминает текущий memory.size и выполняет memory.grow с числом T (второй параметр) и добавляет это в список своих регионов (то, что в dlmalloc называется mstate) и т.д. до тех пор, пока память не закончится. И это всё работает хорошо в одном потоке.