GeezerVison is showing github.com — gh-117139: Convert the evaluation stack to stack refs (#118450) · python/cpython@22b0de2
File treeExpand file treeCollapse file tree Open diff view settings Misc/NEWS.d/next/Core and Builtins
Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: Include/internal/pycore_ceval.h +4-1Lines changed: 4 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -261,8 +261,11 @@ PyAPI_FUNC(void) _PyEval_FormatExcUnbound(PyThreadState *tstate, PyCodeObject *c | 261 | 261 | PyAPI_FUNC(void) _PyEval_FormatKwargsError(PyThreadState *tstate, PyObject *func, PyObject *kwargs); | 262 | 262 | PyAPI_FUNC(PyObject *)_PyEval_MatchClass(PyThreadState *tstate, PyObject *subject, PyObject *type, Py_ssize_t nargs, PyObject *kwargs); | 263 | 263 | PyAPI_FUNC(PyObject *)_PyEval_MatchKeys(PyThreadState *tstate, PyObject *map, PyObject *keys); | 264 | | -PyAPI_FUNC(int) _PyEval_UnpackIterable(PyThreadState *tstate, PyObject *v, int argcnt, int argcntafter, PyObject **sp); | | 264 | +PyAPI_FUNC(int) _PyEval_UnpackIterableStackRef(PyThreadState *tstate, _PyStackRef v, int argcnt, int argcntafter, _PyStackRef *sp); | 265 | 265 | PyAPI_FUNC(void) _PyEval_FrameClearAndPop(PyThreadState *tstate, _PyInterpreterFrame *frame); | | 266 | +PyAPI_FUNC(PyObject **) _PyObjectArray_FromStackRefArray(_PyStackRef *input, Py_ssize_t nargs, PyObject **scratch); | | 267 | + | | 268 | +PyAPI_FUNC(void) _PyObjectArray_Free(PyObject **array, PyObject **scratch); | 266 | 269 |
| 267 | 270 |
| 268 | 271 | /* Bits that can be set in PyThreadState.eval_breaker */ | |
Collapse file Copy file name to clipboardExpand all lines: Include/internal/pycore_code.h +15-14Lines changed: 15 additions & 14 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -8,6 +8,7 @@ extern "C" { | 8 | 8 | # error "this header requires Py_BUILD_CORE define" | 9 | 9 | #endif | 10 | 10 |
| | 11 | +#include "pycore_stackref.h" // _PyStackRef | 11 | 12 | #include "pycore_lock.h" // PyMutex | 12 | 13 | #include "pycore_backoff.h" // _Py_BackoffCounter | 13 | 14 |
| @@ -317,30 +318,30 @@ extern void _PyCode_Clear_Executors(PyCodeObject *code); | 317 | 318 |
| 318 | 319 | /* Specialization functions */ | 319 | 320 |
| 320 | | -extern void _Py_Specialize_LoadSuperAttr(PyObject *global_super, PyObject *cls, | | 321 | +extern void _Py_Specialize_LoadSuperAttr(_PyStackRef global_super, _PyStackRef cls, | 321 | 322 | _Py_CODEUNIT *instr, int load_method); | 322 | | -extern void _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, | | 323 | +extern void _Py_Specialize_LoadAttr(_PyStackRef owner, _Py_CODEUNIT *instr, | 323 | 324 | PyObject *name); | 324 | | -extern void _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, | | 325 | +extern void _Py_Specialize_StoreAttr(_PyStackRef owner, _Py_CODEUNIT *instr, | 325 | 326 | PyObject *name); | 326 | 327 | extern void _Py_Specialize_LoadGlobal(PyObject *globals, PyObject *builtins, | 327 | 328 | _Py_CODEUNIT *instr, PyObject *name); | 328 | | -extern void _Py_Specialize_BinarySubscr(PyObject *sub, PyObject *container, | | 329 | +extern void _Py_Specialize_BinarySubscr(_PyStackRef sub, _PyStackRef container, | 329 | 330 | _Py_CODEUNIT *instr); | 330 | | -extern void _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, | | 331 | +extern void _Py_Specialize_StoreSubscr(_PyStackRef container, _PyStackRef sub, | 331 | 332 | _Py_CODEUNIT *instr); | 332 | | -extern void _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, | | 333 | +extern void _Py_Specialize_Call(_PyStackRef callable, _Py_CODEUNIT *instr, | 333 | 334 | int nargs); | 334 | | -extern void _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, | 335 | | - int oparg, PyObject **locals); | 336 | | -extern void _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, | | 335 | +extern void _Py_Specialize_BinaryOp(_PyStackRef lhs, _PyStackRef rhs, _Py_CODEUNIT *instr, | | 336 | + int oparg, _PyStackRef *locals); | | 337 | +extern void _Py_Specialize_CompareOp(_PyStackRef lhs, _PyStackRef rhs, | 337 | 338 | _Py_CODEUNIT *instr, int oparg); | 338 | | -extern void _Py_Specialize_UnpackSequence(PyObject *seq, _Py_CODEUNIT *instr, | | 339 | +extern void _Py_Specialize_UnpackSequence(_PyStackRef seq, _Py_CODEUNIT *instr, | 339 | 340 | int oparg); | 340 | | -extern void _Py_Specialize_ForIter(PyObject *iter, _Py_CODEUNIT *instr, int oparg); | 341 | | -extern void _Py_Specialize_Send(PyObject *receiver, _Py_CODEUNIT *instr); | 342 | | -extern void _Py_Specialize_ToBool(PyObject *value, _Py_CODEUNIT *instr); | 343 | | -extern void _Py_Specialize_ContainsOp(PyObject *value, _Py_CODEUNIT *instr); | | 341 | +extern void _Py_Specialize_ForIter(_PyStackRef iter, _Py_CODEUNIT *instr, int oparg); | | 342 | +extern void _Py_Specialize_Send(_PyStackRef receiver, _Py_CODEUNIT *instr); | | 343 | +extern void _Py_Specialize_ToBool(_PyStackRef value, _Py_CODEUNIT *instr); | | 344 | +extern void _Py_Specialize_ContainsOp(_PyStackRef value, _Py_CODEUNIT *instr); | 344 | 345 |
| 345 | 346 | #ifdef Py_STATS | 346 | 347 |
| |
Collapse file Copy file name to clipboardExpand all lines: Include/internal/pycore_frame.h +14-13Lines changed: 14 additions & 13 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -11,6 +11,7 @@ extern "C" { | 11 | 11 | #include <stdbool.h> | 12 | 12 | #include <stddef.h> // offsetof() | 13 | 13 | #include "pycore_code.h" // STATS | | 14 | +#include "pycore_stackref.h" // _PyStackRef | 14 | 15 |
| 15 | 16 | /* See Objects/frame_layout.md for an explanation of the frame stack | 16 | 17 | * including explanation of the PyFrameObject and _PyInterpreterFrame | @@ -67,7 +68,7 @@ typedef struct _PyInterpreterFrame { | 67 | 68 | uint16_t return_offset; /* Only relevant during a function call */ | 68 | 69 | char owner; | 69 | 70 | /* Locals and stack */ | 70 | | - PyObject *localsplus[1]; | | 71 | + _PyStackRef localsplus[1]; | 71 | 72 | } _PyInterpreterFrame; | 72 | 73 |
| 73 | 74 | #define _PyInterpreterFrame_LASTI(IF) \ | @@ -78,23 +79,23 @@ static inline PyCodeObject *_PyFrame_GetCode(_PyInterpreterFrame *f) { | 78 | 79 | return (PyCodeObject *)f->f_executable; | 79 | 80 | } | 80 | 81 |
| 81 | | -static inline PyObject **_PyFrame_Stackbase(_PyInterpreterFrame *f) { | 82 | | - return f->localsplus + _PyFrame_GetCode(f)->co_nlocalsplus; | | 82 | +static inline _PyStackRef *_PyFrame_Stackbase(_PyInterpreterFrame *f) { | | 83 | + return (f->localsplus + _PyFrame_GetCode(f)->co_nlocalsplus); | 83 | 84 | } | 84 | 85 |
| 85 | | -static inline PyObject *_PyFrame_StackPeek(_PyInterpreterFrame *f) { | | 86 | +static inline _PyStackRef _PyFrame_StackPeek(_PyInterpreterFrame *f) { | 86 | 87 | assert(f->stacktop > _PyFrame_GetCode(f)->co_nlocalsplus); | 87 | | - assert(f->localsplus[f->stacktop-1] != NULL); | | 88 | + assert(!PyStackRef_IsNull(f->localsplus[f->stacktop-1])); | 88 | 89 | return f->localsplus[f->stacktop-1]; | 89 | 90 | } | 90 | 91 |
| 91 | | -static inline PyObject *_PyFrame_StackPop(_PyInterpreterFrame *f) { | | 92 | +static inline _PyStackRef _PyFrame_StackPop(_PyInterpreterFrame *f) { | 92 | 93 | assert(f->stacktop > _PyFrame_GetCode(f)->co_nlocalsplus); | 93 | 94 | f->stacktop--; | 94 | 95 | return f->localsplus[f->stacktop]; | 95 | 96 | } | 96 | 97 |
| 97 | | -static inline void _PyFrame_StackPush(_PyInterpreterFrame *f, PyObject *value) { | | 98 | +static inline void _PyFrame_StackPush(_PyInterpreterFrame *f, _PyStackRef value) { | 98 | 99 | f->localsplus[f->stacktop] = value; | 99 | 100 | f->stacktop++; | 100 | 101 | } | @@ -143,14 +144,14 @@ _PyFrame_Initialize( | 143 | 144 | frame->owner = FRAME_OWNED_BY_THREAD; | 144 | 145 |
| 145 | 146 | for (int i = null_locals_from; i < code->co_nlocalsplus; i++) { | 146 | | - frame->localsplus[i] = NULL; | | 147 | + frame->localsplus[i] = PyStackRef_NULL; | 147 | 148 | } | 148 | 149 | } | 149 | 150 |
| 150 | 151 | /* Gets the pointer to the locals array | 151 | 152 | * that precedes this frame. | 152 | 153 | */ | 153 | | -static inline PyObject** | | 154 | +static inline _PyStackRef* | 154 | 155 | _PyFrame_GetLocalsArray(_PyInterpreterFrame *frame) | 155 | 156 | { | 156 | 157 | return frame->localsplus; | @@ -160,16 +161,16 @@ _PyFrame_GetLocalsArray(_PyInterpreterFrame *frame) | 160 | 161 | Having stacktop <= 0 ensures that invalid | 161 | 162 | values are not visible to the cycle GC. | 162 | 163 | We choose -1 rather than 0 to assist debugging. */ | 163 | | -static inline PyObject** | | 164 | +static inline _PyStackRef* | 164 | 165 | _PyFrame_GetStackPointer(_PyInterpreterFrame *frame) | 165 | 166 | { | 166 | | - PyObject **sp = frame->localsplus + frame->stacktop; | | 167 | + _PyStackRef *sp = frame->localsplus + frame->stacktop; | 167 | 168 | frame->stacktop = -1; | 168 | 169 | return sp; | 169 | 170 | } | 170 | 171 |
| 171 | 172 | static inline void | 172 | | -_PyFrame_SetStackPointer(_PyInterpreterFrame *frame, PyObject **stack_pointer) | | 173 | +_PyFrame_SetStackPointer(_PyInterpreterFrame *frame, _PyStackRef *stack_pointer) | 173 | 174 | { | 174 | 175 | frame->stacktop = (int)(stack_pointer - frame->localsplus); | 175 | 176 | } | @@ -309,7 +310,7 @@ _PyFrame_PushTrampolineUnchecked(PyThreadState *tstate, PyCodeObject *code, int | 309 | 310 |
| 310 | 311 | PyAPI_FUNC(_PyInterpreterFrame *) | 311 | 312 | _PyEvalFramePushAndInit(PyThreadState *tstate, PyFunctionObject *func, | 312 | | - PyObject *locals, PyObject* const* args, | | 313 | + PyObject *locals, _PyStackRef const* args, | 313 | 314 | size_t argcount, PyObject *kwnames); | 314 | 315 |
| 315 | 316 | #ifdef __cplusplus | |
Collapse file Copy file name to clipboardExpand all lines: Include/internal/pycore_jit.h +1-1Lines changed: 1 addition & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -11,7 +11,7 @@ extern "C" { | 11 | 11 |
| 12 | 12 | #ifdef _Py_JIT | 13 | 13 |
| 14 | | -typedef _Py_CODEUNIT *(*jit_func)(_PyInterpreterFrame *frame, PyObject **stack_pointer, PyThreadState *tstate); | | 14 | +typedef _Py_CODEUNIT *(*jit_func)(_PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState *tstate); | 15 | 15 |
| 16 | 16 | int _PyJIT_Compile(_PyExecutorObject *executor, const _PyUOpInstruction *trace, size_t length); | 17 | 17 | void _PyJIT_Free(_PyExecutorObject *executor); | |
Collapse file Copy file name to clipboardExpand all lines: Include/internal/pycore_object.h -15Lines changed: 0 additions & 15 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -159,21 +159,6 @@ static inline void _Py_ClearImmortal(PyObject *op) | 159 | 159 | op = NULL; \ | 160 | 160 | } while (0) | 161 | 161 |
| 162 | | -// Mark an object as supporting deferred reference counting. This is a no-op | 163 | | -// in the default (with GIL) build. Objects that use deferred reference | 164 | | -// counting should be tracked by the GC so that they are eventually collected. | 165 | | -extern void _PyObject_SetDeferredRefcount(PyObject *op); | 166 | | - | 167 | | -static inline int | 168 | | -_PyObject_HasDeferredRefcount(PyObject *op) | 169 | | -{ | 170 | | -#ifdef Py_GIL_DISABLED | 171 | | - return _PyObject_HAS_GC_BITS(op, _PyGC_BITS_DEFERRED); | 172 | | -#else | 173 | | - return 0; | 174 | | -#endif | 175 | | -} | 176 | | - | 177 | 162 | #if !defined(Py_GIL_DISABLED) | 178 | 163 | static inline void | 179 | 164 | _Py_DECREF_SPECIALIZED(PyObject *op, const destructor destruct) | |
Collapse file Copy file name to clipboard +32Lines changed: 32 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +#ifndef Py_INTERNAL_OBJECT_DEFERRED_H | | 2 | +#define Py_INTERNAL_OBJECT_DEFERRED_H | | 3 | + | | 4 | +#ifdef __cplusplus | | 5 | +extern "C" { | | 6 | +#endif | | 7 | + | | 8 | +#include "pycore_gc.h" | | 9 | + | | 10 | +#ifndef Py_BUILD_CORE | | 11 | +# error "this header requires Py_BUILD_CORE define" | | 12 | +#endif | | 13 | + | | 14 | +// Mark an object as supporting deferred reference counting. This is a no-op | | 15 | +// in the default (with GIL) build. Objects that use deferred reference | | 16 | +// counting should be tracked by the GC so that they are eventually collected. | | 17 | +extern void _PyObject_SetDeferredRefcount(PyObject *op); | | 18 | + | | 19 | +static inline int | | 20 | +_PyObject_HasDeferredRefcount(PyObject *op) | | 21 | +{ | | 22 | +#ifdef Py_GIL_DISABLED | | 23 | + return _PyObject_HAS_GC_BITS(op, _PyGC_BITS_DEFERRED); | | 24 | +#else | | 25 | + return 0; | | 26 | +#endif | | 27 | +} | | 28 | + | | 29 | +#ifdef __cplusplus | | 30 | +} | | 31 | +#endif | | 32 | +#endif // !Py_INTERNAL_OBJECT_DEFERRED_H |
Collapse file Copy file name to clipboardExpand all lines: Include/internal/pycore_optimizer.h +1-1Lines changed: 1 addition & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -271,7 +271,7 @@ extern int _Py_uop_frame_pop(_Py_UOpsContext *ctx); | 271 | 271 |
| 272 | 272 | PyAPI_FUNC(PyObject *) _Py_uop_symbols_test(PyObject *self, PyObject *ignored); | 273 | 273 |
| 274 | | -PyAPI_FUNC(int) _PyOptimizer_Optimize(struct _PyInterpreterFrame *frame, _Py_CODEUNIT *start, PyObject **stack_pointer, _PyExecutorObject **exec_ptr); | | 274 | +PyAPI_FUNC(int) _PyOptimizer_Optimize(struct _PyInterpreterFrame *frame, _Py_CODEUNIT *start, _PyStackRef *stack_pointer, _PyExecutorObject **exec_ptr); | 275 | 275 |
| 276 | 276 | #ifdef __cplusplus | 277 | 277 | } | |
|