GH-150516: Reduce the work done to spill and reload the stack around … · python/cpython@ad1513a

GitHub

@@ -152,6 +152,7 @@ static inline void _PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *

152152// visited is GC bookkeeping for the current stack walk, not frame state.

153153dest->visited=0;

154154#ifdefPy_DEBUG

155+dest->stackpointer_valid=src->stackpointer_valid;

155156dest->lltrace=src->lltrace;

156157#endif

157158for (inti=0; i<stacktop; i++) {

@@ -207,6 +208,7 @@ _PyFrame_Initialize(

207208frame->owner=FRAME_OWNED_BY_THREAD;

208209frame->visited=0;

209210#ifdefPy_DEBUG

211+frame->stackpointer_valid=1;

210212frame->lltrace=0;

211213#endif

212214@@ -230,26 +232,51 @@ _PyFrame_GetLocalsArray(_PyInterpreterFrame *frame)

230232staticinline_PyStackRef*

231233_PyFrame_GetStackPointer(_PyInterpreterFrame*frame)

232234{

235+returnframe->stackpointer;

236+}

237+238+staticinlinevoid

239+_PyFrame_SetStackPointer(_PyInterpreterFrame*frame, _PyStackRef*stack_pointer)

240+{

241+frame->stackpointer=stack_pointer;

242+}

243+244+staticinlinevoid

245+_PyFrame_StackPointerValidate(_PyInterpreterFrame*frame)

246+{

247+#ifdefPy_DEBUG

248+/* Avoid bloating the JIT code */

233249#ifndef_Py_JIT

234-assert(frame->stackpointer!=NULL);

250+assert(frame->stackpointer_valid==0);

235251#endif

236-_PyStackRef*sp=frame->stackpointer;

237-#ifndefNDEBUG

238-frame->stackpointer=NULL;

252+frame->stackpointer_valid=1;

239253#endif

240-returnsp;

241254}

242255243256staticinlinevoid

244-_PyFrame_SetStackPointer(_PyInterpreterFrame*frame, _PyStackRef*stack_pointer)

257+_PyFrame_StackPointerInvalidate(_PyInterpreterFrame*frame)

245258{

259+#ifdefPy_DEBUG

246260/* Avoid bloating the JIT code */

247261#ifndef_Py_JIT

248-assert(frame->stackpointer==NULL);

262+assert(frame->stackpointer_valid==1);

263+#endif

264+frame->stackpointer_valid=0;

249265#endif

250-frame->stackpointer=stack_pointer;

251266}

252267268+staticinlinevoid

269+_PyFrame_StackAssertInvalid(_PyInterpreterFrame*frame)

270+{

271+#ifdefPy_DEBUG

272+/* Avoid bloating the JIT code */

273+#ifndef_Py_JIT

274+assert(frame->stackpointer_valid==0);

275+#endif

276+#endif

277+}

278+279+253280/* Determine whether a frame is incomplete.

254281 * A frame is incomplete if it is part way through

255282 * creating cell objects or a generator or coroutine.

@@ -411,6 +438,7 @@ _PyFrame_PushTrampolineUnchecked(PyThreadState *tstate, PyCodeObject *code, int

411438frame->owner=FRAME_OWNED_BY_THREAD;

412439frame->visited=0;

413440#ifdefPy_DEBUG

441+frame->stackpointer_valid=1;

414442frame->lltrace=0;

415443#endif

416444frame->return_offset=0;