So in the general case, a program uses both memory in the stack (automatically managed) and heap (garbage collected or manually managed).
What is the class of programs that can be compiled to use memory in a stack-like fashion only and no heap allocation? Is it still Turing-complete with some other trade off (e.g. code blow-up) or it's a weaker language class?
If by stack you mean the abstract data type which can only be accessed at the top, you're looking at pushdown automata. Deterministic PDAs can only handle deterministic context-free languages, non-deterministic PDAs all context-free languages, so they are not Turing complete.
However, the "stack" in real computer architectures is not like that. Allocating and deallocating memory happens in a LIFO fashion, but all allocated memory is random access, so an unbounded stack of this kind would be as Turing complete as any RAM. Of course, the stack in any real operating system is of fixed size, but limits of the word size and virtual memory nonwithstanding, it can be set arbitrarily large, so if you call a computer with heap allocation Turing complete, you shouldn't have trouble calling this machine Turing complete.
In fact, some region systems are quite close to this approach. Regions are distinguished from stack allocations at the conceptual level, but when regions are nested (letregion ρ in ...
), they effectively obey a stack discipline. The usual problem of (pure) region systems is internal fragmentation: A region can only be deallocated when all objects in it are dead, which leads to greatly increased memory requirements for some programs. So no code blow up, but memory blow up.
Finally, even if the language only provides a stack, getting a "heap" is as simple as allocating a large byte array from the stack and implementing your own, more flexible memory management on it. That is, after all, what all other heaps do.