I haven't worked with production-quality VMs, but here are my five cents.
.text sections in Unix executables belong to the file which stores executable code; at run-time this file section is mapped to a memory area allocated by the system linker during program initialization, that's all (on Linux, you can see the sections layout in memory in /proc/$PID/maps).
As for JIT-compilation on Unix-like systems, I can only think of memory areas which have been allocated by mmap system call with PROT_EXEC flag enabled. This call is specified by POSIX standards and used by the Linux's system linker, ld.so, to load any native executable file into memory. This call can be equally used for allocating new executable memory areas at run-time.
The usual heap is often protected by OS/MMU from being executed, as any /proc/$PID/maps file suggests:
00dd4000-01292000 rw-p 00000000 00:00 0                  [heap]
here rw-p means that no data in [heap] can be executed (though, e.g., it is not the case with 32-bit x86 CPUs without PAE, they don't have hardware capability to prevent running some memory data as code), but can be read/written. 
So a VM needs a dedicated memory area with code execution permission. Indeed, let's look for rwx memory areas in some java process memory layout:
# cat /proc/12929/maps | grep rwx        # I run a Java VM with PID 12929
f3700000-f3940000 rwxp 00000000 00:00 0  # - an unnamed executable & writable region
Then execution of native code is a matter of assembling JIT-compiled native code either position-independently (like shared objects code is compiled, with gcc option -fPIC) or using the address returned by mmap().