Skip to content

Commit

Permalink
Stackless issue python#282: Refactor slp_eval_frame
Browse files Browse the repository at this point in the history
Decouple the cleanup logic for initial stubs of sub-interpreters from
the stack handling. Previously this logic depended on the value of
SLP_CSTACK_GOODGAP being positive.
  • Loading branch information
akruis authored Jul 9, 2021
1 parent e511c4c commit 33b8f81
Showing 1 changed file with 47 additions and 39 deletions.
86 changes: 47 additions & 39 deletions Stackless/core/stacklesseval.c
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ slp_eval_frame(PyFrameObject *f)
PyThreadState *ts = _PyThreadState_GET();
PyFrameObject *fprev = f->f_back;
intptr_t * stackref;
int set_cstack_base;
PyObject *retval;

if (fprev == NULL && ts->st.main == NULL) {
Expand Down Expand Up @@ -345,51 +346,58 @@ slp_eval_frame(PyFrameObject *f)

/* mark the stack base */
stackref = SLP_STACK_REFPLUS + (intptr_t *) &f;
if (ts->st.cstack_base == NULL)
set_cstack_base = ts->st.cstack_base == NULL;
if (set_cstack_base)
ts->st.cstack_base = stackref - SLP_CSTACK_GOODGAP;
if (stackref > ts->st.cstack_base) {
PyCStackObject *initial_stub;
retval = climb_stack_and_eval_frame(f);
initial_stub = ts->st.initial_stub;
/* cst might be NULL in OOM conditions */
if (ts->interp != _PyRuntime.interpreters.main && initial_stub != NULL) {
PyCStackObject *cst;
register int found = 0;
assert(initial_stub->startaddr == ts->st.cstack_base);
for (cst = initial_stub->next; cst != initial_stub; cst = cst->next) {
if (Py_SIZE(cst) != 0 && cst->task != NULL &&
cst->tstate == ts) {
assert(cst->startaddr == ts->st.cstack_base);
found = 1;
break;
}
}
if (!found) {
Py_CLEAR(ts->st.initial_stub);
ts->st.cstack_base = NULL;
ts->st.cstack_root = NULL;
}
retval = climb_stack_and_eval_frame(f); /* recursively calls slp_eval_frame(f) */
} else {
assert(SLP_CURRENT_FRAME(ts) == NULL); /* else we would change the current frame */
SLP_STORE_NEXT_FRAME(ts, f);
returning = make_initial_stub();
if (returning < 0)
return NULL;
/* returning will be 1 if we "switched back" to this stub, and 0
* if this is the original call that just created the stub.
* If the stub is being reused, the argument, i.e. the frame,
* is in ts->frame
*/
SLP_ASSERT_FRAME_IN_TRANSFER(ts);
if (returning != 1) {
assert(f == SLP_PEEK_NEXT_FRAME(ts));
}
return retval;
assert(ts->interp->st.initial_tstate != NULL);
assert(ts->interp->st.mem_bomb != NULL);

retval = slp_run_tasklet();
}

assert(SLP_CURRENT_FRAME(ts) == NULL); /* else we would change the current frame */
SLP_STORE_NEXT_FRAME(ts, f);
returning = make_initial_stub();
if (returning < 0)
return NULL;
/* returning will be 1 if we "switched back" to this stub, and 0
* if this is the original call that just created the stub.
* If the stub is being reused, the argument, i.e. the frame,
* is in ts->frame
*/
SLP_ASSERT_FRAME_IN_TRANSFER(ts);
if (returning != 1) {
assert(f == SLP_PEEK_NEXT_FRAME(ts));
/* Clear the initial stub, except for the main interpreter.
* Without this code, terminating sub-interpreters would leak references. */
if (set_cstack_base /* only for the outermost call */
&& ts->interp != _PyRuntime.interpreters.main /* not for the main interpreter */
&& ts->st.initial_stub != NULL) /* not yet cleared */
{
PyCStackObject *initial_stub = ts->st.initial_stub;
PyCStackObject *cst;
register int found = 0;
assert(initial_stub->startaddr == ts->st.cstack_base);
for (cst = initial_stub->next; cst != initial_stub; cst = cst->next) {
if (Py_SIZE(cst) != 0 && cst->task != NULL &&
cst->tstate == ts) {
assert(cst->startaddr == ts->st.cstack_base);
found = 1; /* Initial stub is still in use. */
break;
}
}
if (!found) {
/* This initial stub is no longer in use, free it */
Py_CLEAR(ts->st.initial_stub);
ts->st.cstack_base = NULL;
ts->st.cstack_root = NULL;
}
}
assert(ts->interp->st.initial_tstate != NULL);
assert(ts->interp->st.mem_bomb != NULL);
return slp_run_tasklet();
return retval;
}
assert(ts->interp->st.initial_tstate != NULL);
assert(ts->interp->st.mem_bomb != NULL); /* see above */
Expand Down

0 comments on commit 33b8f81

Please sign in to comment.