[webkit-help] JSC call stack layout details

Eric Hennigan eric.hennigan at uci.edu
Fri Oct 14 09:34:01 PDT 2011


Hello fellow hackers,

   I've been working on JSC (interpreter only, not JIT) for a month
or so now, and so I'm somewhat familiar with the internals. However,
I've reached a point where I feel that some external commentary (from
those who've been around longer) would be beneficial. I was wondering
if anyone on this list could spare the time to answer the following
questions about how JSC handles the call stack. I will give a brief
overview of my current understanding before asking the questions. If
anything I say is in some way misguided, please correct it.

   My current understanding is that JSC::Interpreter contains a
RegisterFile, which can be thought of as an array of bytes. Calling a
function is done in a 3 step fashion: push arguments, place call
frame, call. Returning can simply pop both the arguments and frame by
restoring the stack pointer. The bytecompiler keeps track of the
number of local and temporary values necessary to execute the
function.

   Question 1.

   Is there a safety mechanism for accessing registers from the
callFrame? and if so, how does it relate to
Interpreter::slideRegisterWindowForCall(...)? I've noticed that
CallFrame::r(int) simply returns an offset from the callframe's base
address. There is no check that this offset might be beyond the end of
the RegisterFile. I also notice that there is no check for the total
amount of space (arguments + callframe + locals + temps) that a
function will use before the frame is setup with
Interpreter::slideRegisterWindowForCall(...). However, there is a
check for the amount of space that the callframe will occupy.

   Question 2.

   Since JavaScript has first class function objects and support
continuations, how is the state of a function preserved? Does the
(arguments + callframe + locals + temps) get copied out int heap, as a
JSActivation? It didn't look like this was the case. I'm curious
because continuations mean you end up with a cactus stack, which does
not play well with the linear sequence of callframes I described
above.

   Question 3.

   My pet project requires that each activation record hold a small
stack-like data structure, which is manipulated at runtime. This
structure must reside with the activation record. That is, if the
function is a continuation, the data structure, and its state, must be
preserved across calls. I currently perform an analysis during parsing
which allows me to know the maximum number of entries in the stack
(just as we can know the number of locals, temps and scopes).

   Option 1. Because this data structure works similarly to temporary
variables, I was considering reserving the appropriate amount of space
in the RegisterFile when the callframe is setup.

   Option 2. Alternatively, I was considering hanging off the data
structure as a separate entity. I can easily add another fixed entry
to the CallFrame (alongside the argument count, caller frame, callee,
scope chain, return address and code block). This slot can then point
to my data structure. I worry a bit over memory management though. I'd
want to de-alloc my data structure when the call frame becomes
inactive. I'm ok with inheriting JSObject, and placing it in the
garbage collected heap.


   I thank you in advance for your time and patience,
--
Eric Hennigan


More information about the webkit-help mailing list