vnmakarov / mir

A lightweight JIT compiler based on MIR (Medium Internal Representation) and C11 JIT compiler and interpreter based on MIR
MIT License
2.24k stars 147 forks source link

Get the size and start address of the stack segment #275

Open zhao-huang opened 2 years ago

zhao-huang commented 2 years ago

Hi, there! I want to implement support for infinite recursion and continuation in my language by releasing stack with trampoline before they grow big enough to cause an overflow. In MIR, it is very convenient to use MIR_BSTART to get the current stack pointer of the function, but I wonder if there is any way to get the size and start address of the stack segment.

vnmakarov commented 2 years ago

I wonder if there is any way to get the size and start address of the stack segment. Sorry, no. The first stack can grow in function in many cases therefore size of the stack is hard to calculate.

Start address of the function stack is hard to get too. It is machine-dependent. For x86-64, bp register shows start address + 16 byte (ret address and saved bp). But for some funcs bp reg can be undefined.

I am not sure but may be a new feature on branch bbv can be useful for this. It is call of func (w/o args) by jump and returning from the func by another jump. Such call will work correctly even if you use stack in the func (e.g. for local vars or saving/restoring callee-saved regs). I use this feature to quick switch from interpreter to jit code where interpreter uses direct threaded code (by using labels as values extension). Return by jump is just a jump to label address in the interpreter code execution the next insn.

On MIR level, there are new insns JCALL and JRET. On c2m level, there are 2 new bultins: __builtin_jcal (func) and __builting_jret(return address).

In the future, when I implement debug info, the info about the stack will be possible to calculate.

zhao-huang commented 2 years ago

@vnmakarov Thanks for your reply! Yes, stack switching that saves function context is a very useful feature, and I will need it. I'm trying to implement delimited continuations in a DSL, and if MIR provides stack switching primitives, then I can implement it in a "linked-list of fibers" way without converting code to continuation-passing style. At the same time, I'm curious if the current MIR stack will grow automatically (like GCC's split stacks), which would make it easier to implement such language runtimes.

vnmakarov commented 2 years ago

OK. I'll think what MIR features should be added to make possible fibers implementation and split stacks.