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 _______________________________________________ webkit-help mailing list [email protected] http://lists.webkit.org/mailman/listinfo.cgi/webkit-help
