It very much is necessary. Take the linux kernel's eBPF interpreter for example. Since the code runs in kernel scope and in many critical places (system call interception, network processing) it's important that the code executes within a bounded amount of time.
I think its restrictions are that it only allows forward jumps and a limited amount of instructions.