Making the C stack invisible to bytecode by inserting shim frames #391
markshannon
started this conversation in
Ideas
Replies: 1 comment 1 reply
-
Are you planning on working on this? If not, I’d like to take it. I’m going to be picking the |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Motivation
The
RETURN_VALUE
instruction needs check to whether the current frame is an "entry" frame (it was the frame that was passed toPyEval_EvalFrameDefault
) and either do an "internal" return (pop the frame, and continue in the caller frame) or an "external" return (do a return in the C code).This isn't a big deal deal for
RETURN_VALUE
, but could get cumbersome if we want to do the same forYIELD_VALUE
, to alloweffective specialization of
FOR_ITER
for generators, and specialization ofSEND
for coroutines.By inserting a shim frame on entry to
PyEval_EvalFrameDefault
and ingen.send
we can shieldRETURN_VALUE
andYIELD_VALUE
from knowing anything about the C stack.Shim frame
A shim frame is a
_PyInterpreterFrame
inserted into the stack on entry toPyEval_EvalFrameDefault
. The code object for a shim frame would consist of the single instructionEXIT
, which would perform a C return.Cost/benefit
Every call to
PyEval_EvalFrameDefault
would suffer additional cost of pushing a_PyInterpreterFrame
, whereas everyRETURN_VALUE
would only save the cost of a single branch. Unless the number ofRETURN_VALUE
s is a lot more than the number of calls toPyEval_EvalFrameDefault
then it clearly isn't worth doing at the moment.However, once we want to specialize
YIELD_VALUE
, then this starts to make a lot more sense, as we can implementgen.send
in bytecode that converts a yield into a return and wraps a return value in aStopIteration
Specializations of
FOR_ITER
andSEND
If we add another "return address" to
_PyInterpreterFrame
(or just an offset from the currentprev_instr
) thenYIELD_VALUE
can jump to that, much asRETURN_VALUE
jumps toprev_instr
.The specialization of
FOR_ITER
for generators would set this additional "return address", push the generator's frame and jump into that frame.The specialization of
SEND
for coroutines would do much the same, asFOR_ITER
is basicallyLOAD_CONST None; SEND
.Beta Was this translation helpful? Give feedback.
All reactions