Skip to content

Commit 600f4db

Browse files
authored
GH-145668: Add FOR_ITER specialization for virtual iterators. Specialize GET_ITER. (GH-147967)
* Add FOR_ITER_VIRTUAL to specialize FOR_ITER for virtual iterators * Add GET_ITER_SELF to specialize GET_ITER for iterators (including generators) * Add GET_ITER_VIRTUAL to specialize GET_ITER for iterables as virtual iterators * Add new (internal) _tp_iteritem function slot to PyTypeObject * Put limited RESUME at start of genexpr for free-threading. Fix up exception handling in genexpr
1 parent 0fcf2b7 commit 600f4db

37 files changed

+2988
-1535
lines changed

Include/cpython/object.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,8 @@ struct _typeobject {
230230
destructor tp_finalize;
231231
vectorcallfunc tp_vectorcall;
232232

233+
/* Below here all fields are internal to the VM */
234+
233235
/* bitset of which type-watchers care about this type */
234236
unsigned char tp_watched;
235237

@@ -239,6 +241,7 @@ struct _typeobject {
239241
* Otherwise, limited to MAX_VERSIONS_PER_CLASS (defined elsewhere).
240242
*/
241243
uint16_t tp_versions_used;
244+
_Py_iteritemfunc _tp_iteritem; /* Virtual iterator next function */
242245
};
243246

244247
#define _Py_ATTR_CACHE_UNUSED (30000) // (see tp_versions_used)

Include/internal/pycore_code.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,12 @@ typedef struct {
141141

142142
#define INLINE_CACHE_ENTRIES_FOR_ITER CACHE_ENTRIES(_PyForIterCache)
143143

144+
typedef struct {
145+
_Py_BackoffCounter counter;
146+
} _PyGetIterCache;
147+
148+
#define INLINE_CACHE_ENTRIES_GET_ITER CACHE_ENTRIES(_PyGetIterCache)
149+
144150
typedef struct {
145151
_Py_BackoffCounter counter;
146152
} _PySendCache;
@@ -324,6 +330,7 @@ PyAPI_FUNC(void) _Py_Specialize_ContainsOp(_PyStackRef value, _Py_CODEUNIT *inst
324330
PyAPI_FUNC(void) _Py_GatherStats_GetIter(_PyStackRef iterable);
325331
PyAPI_FUNC(void) _Py_Specialize_CallFunctionEx(_PyStackRef func_st, _Py_CODEUNIT *instr);
326332
PyAPI_FUNC(void) _Py_Specialize_Resume(_Py_CODEUNIT *instr, PyThreadState *tstate, _PyInterpreterFrame *frame);
333+
PyAPI_FUNC(void) _Py_Specialize_GetIter(_PyStackRef iterable, _Py_CODEUNIT *instr);
327334

328335
// Utility functions for reading/writing 32/64-bit values in the inline caches.
329336
// Great care should be taken to ensure that these functions remain correct and

Include/internal/pycore_magic_number.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ Known values:
295295
Python 3.15a8 3662 (Add counter to RESUME)
296296
Python 3.15a8 3663 (Merge GET_ITER and GET_YIELD_FROM_ITER. Modify SEND to make it a bit more like FOR_ITER)
297297
Python 3.15a8 3664 (Fix __qualname__ for __annotate__ functions)
298+
Python 3.15a8 3665 (Add FOR_ITER_VIRTUAL and GET_ITER specializations)
298299
299300
300301
Python 3.16 will start with 3700
@@ -308,7 +309,7 @@ PC/launcher.c must also be updated.
308309
309310
*/
310311

311-
#define PYC_MAGIC_NUMBER 3664
312+
#define PYC_MAGIC_NUMBER 3665
312313
/* This is equivalent to converting PYC_MAGIC_NUMBER to 2 bytes
313314
(little-endian) and then appending b'\r\n'. */
314315
#define PYC_MAGIC_NUMBER_TOKEN \

Include/internal/pycore_opcode_metadata.h

Lines changed: 27 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_opcode_utils.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,10 @@ extern "C" {
8282
#define RESUME_AFTER_YIELD 1
8383
#define RESUME_AFTER_YIELD_FROM 2
8484
#define RESUME_AFTER_AWAIT 3
85+
#define RESUME_AT_GEN_EXPR_START 4
8586

86-
#define RESUME_OPARG_LOCATION_MASK 0x3
87-
#define RESUME_OPARG_DEPTH1_MASK 0x4
87+
#define RESUME_OPARG_LOCATION_MASK 0x7
88+
#define RESUME_OPARG_DEPTH1_MASK 0x8
8889

8990
#define GET_ITER_YIELD_FROM 1
9091
#define GET_ITER_YIELD_FROM_NO_CHECK 2

0 commit comments

Comments
 (0)