----------------------------------------------------------------------
Stackframe layout conventions - Intel version.
-----------------------------------------------------------------------
A stack is an array of "slots", declared formally as integers, each slot
containing either a primitive (byte, int, float, etc), an object pointer,
a machine code pointer (a return address pointer), or a pointer to another
slot in the same stack (a frame pointer). The interpretation of a slot's
contents depends on the current value of IP, the machine instruction
address register.
Each machine code generator provides maps, for use by the garbage collector,
that tell how to interpret the stack slots at "safe points" in the
program's execution.
Here's a picture of what a stack might look like in memory.
Note: this (array) object is drawn upside down compared to other objects
because the hardware stack grows from high memory to low memory, but
array objects are layed out from low memory to high (header first).
hi-memory +---------------+ ... | IP=0 | . +---------------+ . +-> | FP=0 | <-- "end of vm stack" sentinel . | +---------------+ . caller's frame | | cmid=0 | <-- "invisible method" id . | +---------------+ ---. | | parameter0 | \ | . | +---------------+ \ parameter area | . | | parameter1 | / (== caller's operand stack area) | . --- | +---------------+ / |... | | | saved IP | <-- return address (in caller) | | \ +---------------+ | header FP-> | saved FP | <-- this frame's caller's frame | | +---------------+ | | | cmid | <-- this frame's compiledmethod id | | +---------------+ | | | saved GPRs | \ | | +---------------+ \ nonvolatile register save area | | | saved FPRS | / | frame | +---------------+ | | | local0 | \ | body +---------------+ \_local variables area | | | local1 | / | | +---------------+ / | | | operand0 | \ | | +---------------+ \_operand stack area | | SP-> | operand1 | / | | +---------------+ / | | | ... | | --- +===============+ --- | ... | +---------------+ stackLimit-> | ... | \ +---------------+ \_guard region for detecting & processing stack overflow | ... | / +---------------+ / |(object header)| low-memory +---------------+ The opt compiler uses a different stackframe layout hi-memory +---------------+ ... | IP=0 | . +---------------+ . +-> | FP=0 | <-- "end of vm stack" sentinel . | +---------------+ . caller's frame | | cmid=-1 | <-- "invisible method" id . | +---------------+ ---. | | parameter0 | \ | . | +---------------+ \ parameter area | . | | parameter1 | / (== caller's operand stack area) | . --- | +---------------+ / |... | | | saved IP | <-- return address (in caller) | | \ +---------------+ | header FP-> | saved FP | <-- this frame's caller's frame | | +---------------+ | | | cmid | <-- this frame's compiledmethod id | --- +---------------+ | | | | | | | Spill Area | <-- spills and other method-specific | | | ... | compiler-managed storage | | +---------------+ | | | Saved FP | only SaveVolatile Frames | | | State | | | +---------------+ | | | VolGPR[0] | | | | ... | only SaveVolatile Frames | | | VolGPR[n] | | | +---------------+ | body | NVolGPR[k] | <-- info.getUnsignedNonVolatileOffset() | frame | | ... | k == info.getFirstNonVolatileGPR() | | | NVolGPR[n] | | | +---------------+ | | | NVolFPR[k] | | | | ... | k == info.getFirstNonVolatileFPR() | | | NVolFPR[n] | | | +---------------+ | | | parameter0 | \ | | +---------------+ \_parameters to callee frame | | SP-> | parameter1 | / | | +---------------+ / | | | ... | | --- +===============+ --- | ... | +---------------+ stackLimit-> | ... | \ +---------------+ \_guard region for detecting & processing stack overflow | ... | / +---------------+ / |(object header)| low-memory +---------------+