From 5f147c61b5d4f38b963dc461f032f5f0b0d92b75 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Wed, 22 Jun 2022 01:35:48 +0900 Subject: [PATCH 1/5] Implement FOR_ITER_SET --- Include/internal/pycore_opcode.h | 27 ++++++------- Include/internal/pycore_set.h | 24 ++++++++++++ Include/opcode.h | 65 ++++++++++++++++---------------- Lib/opcode.py | 1 + Makefile.pre.in | 1 + Objects/setobject.c | 64 ++++++++++++++++--------------- PCbuild/pythoncore.vcxproj | 1 + Python/ceval.c | 20 ++++++++++ Python/opcode_targets.h | 24 ++++++------ Python/specialize.c | 4 ++ 10 files changed, 144 insertions(+), 87 deletions(-) create mode 100644 Include/internal/pycore_set.h diff --git a/Include/internal/pycore_opcode.h b/Include/internal/pycore_opcode.h index b9195f5c3299dc..d3d34da76524fa 100644 --- a/Include/internal/pycore_opcode.h +++ b/Include/internal/pycore_opcode.h @@ -127,6 +127,7 @@ const uint8_t _PyOpcode_Deopt[256] = { [FOR_ITER_ADAPTIVE] = FOR_ITER, [FOR_ITER_LIST] = FOR_ITER, [FOR_ITER_RANGE] = FOR_ITER, + [FOR_ITER_SET] = FOR_ITER, [GET_AITER] = GET_AITER, [GET_ANEXT] = GET_ANEXT, [GET_AWAITABLE] = GET_AWAITABLE, @@ -311,6 +312,7 @@ const uint8_t _PyOpcode_Original[256] = { [FOR_ITER_ADAPTIVE] = FOR_ITER, [FOR_ITER_LIST] = FOR_ITER, [FOR_ITER_RANGE] = FOR_ITER, + [FOR_ITER_SET] = FOR_ITER, [GET_AITER] = GET_AITER, [GET_ANEXT] = GET_ANEXT, [GET_AWAITABLE] = GET_AWAITABLE, @@ -488,29 +490,29 @@ static const char *const _PyOpcode_OpName[256] = { [DELETE_SUBSCR] = "DELETE_SUBSCR", [FOR_ITER_LIST] = "FOR_ITER_LIST", [FOR_ITER_RANGE] = "FOR_ITER_RANGE", + [FOR_ITER_SET] = "FOR_ITER_SET", [JUMP_BACKWARD_QUICK] = "JUMP_BACKWARD_QUICK", [LOAD_ATTR_ADAPTIVE] = "LOAD_ATTR_ADAPTIVE", [LOAD_ATTR_CLASS] = "LOAD_ATTR_CLASS", - [LOAD_ATTR_INSTANCE_VALUE] = "LOAD_ATTR_INSTANCE_VALUE", [GET_ITER] = "GET_ITER", [GET_YIELD_FROM_ITER] = "GET_YIELD_FROM_ITER", [PRINT_EXPR] = "PRINT_EXPR", [LOAD_BUILD_CLASS] = "LOAD_BUILD_CLASS", + [LOAD_ATTR_INSTANCE_VALUE] = "LOAD_ATTR_INSTANCE_VALUE", [LOAD_ATTR_MODULE] = "LOAD_ATTR_MODULE", - [LOAD_ATTR_PROPERTY] = "LOAD_ATTR_PROPERTY", [LOAD_ASSERTION_ERROR] = "LOAD_ASSERTION_ERROR", [RETURN_GENERATOR] = "RETURN_GENERATOR", + [LOAD_ATTR_PROPERTY] = "LOAD_ATTR_PROPERTY", [LOAD_ATTR_SLOT] = "LOAD_ATTR_SLOT", [LOAD_ATTR_WITH_HINT] = "LOAD_ATTR_WITH_HINT", [LOAD_ATTR_METHOD_LAZY_DICT] = "LOAD_ATTR_METHOD_LAZY_DICT", [LOAD_ATTR_METHOD_NO_DICT] = "LOAD_ATTR_METHOD_NO_DICT", [LOAD_ATTR_METHOD_WITH_DICT] = "LOAD_ATTR_METHOD_WITH_DICT", - [LOAD_ATTR_METHOD_WITH_VALUES] = "LOAD_ATTR_METHOD_WITH_VALUES", [LIST_TO_TUPLE] = "LIST_TO_TUPLE", [RETURN_VALUE] = "RETURN_VALUE", [IMPORT_STAR] = "IMPORT_STAR", [SETUP_ANNOTATIONS] = "SETUP_ANNOTATIONS", - [LOAD_CONST__LOAD_FAST] = "LOAD_CONST__LOAD_FAST", + [LOAD_ATTR_METHOD_WITH_VALUES] = "LOAD_ATTR_METHOD_WITH_VALUES", [ASYNC_GEN_WRAP] = "ASYNC_GEN_WRAP", [PREP_RERAISE_STAR] = "PREP_RERAISE_STAR", [POP_EXCEPT] = "POP_EXCEPT", @@ -537,7 +539,7 @@ static const char *const _PyOpcode_OpName[256] = { [JUMP_FORWARD] = "JUMP_FORWARD", [JUMP_IF_FALSE_OR_POP] = "JUMP_IF_FALSE_OR_POP", [JUMP_IF_TRUE_OR_POP] = "JUMP_IF_TRUE_OR_POP", - [LOAD_FAST__LOAD_CONST] = "LOAD_FAST__LOAD_CONST", + [LOAD_CONST__LOAD_FAST] = "LOAD_CONST__LOAD_FAST", [POP_JUMP_FORWARD_IF_FALSE] = "POP_JUMP_FORWARD_IF_FALSE", [POP_JUMP_FORWARD_IF_TRUE] = "POP_JUMP_FORWARD_IF_TRUE", [LOAD_GLOBAL] = "LOAD_GLOBAL", @@ -545,7 +547,7 @@ static const char *const _PyOpcode_OpName[256] = { [CONTAINS_OP] = "CONTAINS_OP", [RERAISE] = "RERAISE", [COPY] = "COPY", - [LOAD_FAST__LOAD_FAST] = "LOAD_FAST__LOAD_FAST", + [LOAD_FAST__LOAD_CONST] = "LOAD_FAST__LOAD_CONST", [BINARY_OP] = "BINARY_OP", [SEND] = "SEND", [LOAD_FAST] = "LOAD_FAST", @@ -565,9 +567,9 @@ static const char *const _PyOpcode_OpName[256] = { [STORE_DEREF] = "STORE_DEREF", [DELETE_DEREF] = "DELETE_DEREF", [JUMP_BACKWARD] = "JUMP_BACKWARD", - [LOAD_GLOBAL_ADAPTIVE] = "LOAD_GLOBAL_ADAPTIVE", + [LOAD_FAST__LOAD_FAST] = "LOAD_FAST__LOAD_FAST", [CALL_FUNCTION_EX] = "CALL_FUNCTION_EX", - [LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN", + [LOAD_GLOBAL_ADAPTIVE] = "LOAD_GLOBAL_ADAPTIVE", [EXTENDED_ARG] = "EXTENDED_ARG", [LIST_APPEND] = "LIST_APPEND", [SET_ADD] = "SET_ADD", @@ -577,35 +579,35 @@ static const char *const _PyOpcode_OpName[256] = { [YIELD_VALUE] = "YIELD_VALUE", [RESUME] = "RESUME", [MATCH_CLASS] = "MATCH_CLASS", + [LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN", [LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE", - [RESUME_QUICK] = "RESUME_QUICK", [FORMAT_VALUE] = "FORMAT_VALUE", [BUILD_CONST_KEY_MAP] = "BUILD_CONST_KEY_MAP", [BUILD_STRING] = "BUILD_STRING", + [RESUME_QUICK] = "RESUME_QUICK", [STORE_ATTR_ADAPTIVE] = "STORE_ATTR_ADAPTIVE", [STORE_ATTR_INSTANCE_VALUE] = "STORE_ATTR_INSTANCE_VALUE", [STORE_ATTR_SLOT] = "STORE_ATTR_SLOT", - [STORE_ATTR_WITH_HINT] = "STORE_ATTR_WITH_HINT", [LIST_EXTEND] = "LIST_EXTEND", [SET_UPDATE] = "SET_UPDATE", [DICT_MERGE] = "DICT_MERGE", [DICT_UPDATE] = "DICT_UPDATE", + [STORE_ATTR_WITH_HINT] = "STORE_ATTR_WITH_HINT", [STORE_FAST__LOAD_FAST] = "STORE_FAST__LOAD_FAST", [STORE_FAST__STORE_FAST] = "STORE_FAST__STORE_FAST", [STORE_SUBSCR_ADAPTIVE] = "STORE_SUBSCR_ADAPTIVE", [STORE_SUBSCR_DICT] = "STORE_SUBSCR_DICT", - [STORE_SUBSCR_LIST_INT] = "STORE_SUBSCR_LIST_INT", [CALL] = "CALL", [KW_NAMES] = "KW_NAMES", [POP_JUMP_BACKWARD_IF_NOT_NONE] = "POP_JUMP_BACKWARD_IF_NOT_NONE", [POP_JUMP_BACKWARD_IF_NONE] = "POP_JUMP_BACKWARD_IF_NONE", [POP_JUMP_BACKWARD_IF_FALSE] = "POP_JUMP_BACKWARD_IF_FALSE", [POP_JUMP_BACKWARD_IF_TRUE] = "POP_JUMP_BACKWARD_IF_TRUE", + [STORE_SUBSCR_LIST_INT] = "STORE_SUBSCR_LIST_INT", [UNPACK_SEQUENCE_ADAPTIVE] = "UNPACK_SEQUENCE_ADAPTIVE", [UNPACK_SEQUENCE_LIST] = "UNPACK_SEQUENCE_LIST", [UNPACK_SEQUENCE_TUPLE] = "UNPACK_SEQUENCE_TUPLE", [UNPACK_SEQUENCE_TWO_TUPLE] = "UNPACK_SEQUENCE_TWO_TUPLE", - [181] = "<181>", [182] = "<182>", [183] = "<183>", [184] = "<184>", @@ -684,7 +686,6 @@ static const char *const _PyOpcode_OpName[256] = { #endif #define EXTRA_CASES \ - case 181: \ case 182: \ case 183: \ case 184: \ diff --git a/Include/internal/pycore_set.h b/Include/internal/pycore_set.h new file mode 100644 index 00000000000000..f67e41b67b1692 --- /dev/null +++ b/Include/internal/pycore_set.h @@ -0,0 +1,24 @@ +#ifndef Py_INTERNAL_SET_H +#define Py_INTERNAL_SET_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +typedef struct { + PyObject_HEAD + PySetObject *si_set; /* Set to NULL when iterator is exhausted */ + Py_ssize_t si_used; + Py_ssize_t si_pos; + Py_ssize_t len; +} _PySetIterObject; + +int _PySetIter_GetNext(_PySetIterObject *si, PyObject**); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_SET_H */ diff --git a/Include/opcode.h b/Include/opcode.h index 7a22d5257a669b..e59b51265eecde 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -158,38 +158,39 @@ extern "C" { #define FOR_ITER_ADAPTIVE 59 #define FOR_ITER_LIST 62 #define FOR_ITER_RANGE 63 -#define JUMP_BACKWARD_QUICK 64 -#define LOAD_ATTR_ADAPTIVE 65 -#define LOAD_ATTR_CLASS 66 -#define LOAD_ATTR_INSTANCE_VALUE 67 -#define LOAD_ATTR_MODULE 72 -#define LOAD_ATTR_PROPERTY 73 -#define LOAD_ATTR_SLOT 76 -#define LOAD_ATTR_WITH_HINT 77 -#define LOAD_ATTR_METHOD_LAZY_DICT 78 -#define LOAD_ATTR_METHOD_NO_DICT 79 -#define LOAD_ATTR_METHOD_WITH_DICT 80 -#define LOAD_ATTR_METHOD_WITH_VALUES 81 -#define LOAD_CONST__LOAD_FAST 86 -#define LOAD_FAST__LOAD_CONST 113 -#define LOAD_FAST__LOAD_FAST 121 -#define LOAD_GLOBAL_ADAPTIVE 141 -#define LOAD_GLOBAL_BUILTIN 143 -#define LOAD_GLOBAL_MODULE 153 -#define RESUME_QUICK 154 -#define STORE_ATTR_ADAPTIVE 158 -#define STORE_ATTR_INSTANCE_VALUE 159 -#define STORE_ATTR_SLOT 160 -#define STORE_ATTR_WITH_HINT 161 -#define STORE_FAST__LOAD_FAST 166 -#define STORE_FAST__STORE_FAST 167 -#define STORE_SUBSCR_ADAPTIVE 168 -#define STORE_SUBSCR_DICT 169 -#define STORE_SUBSCR_LIST_INT 170 -#define UNPACK_SEQUENCE_ADAPTIVE 177 -#define UNPACK_SEQUENCE_LIST 178 -#define UNPACK_SEQUENCE_TUPLE 179 -#define UNPACK_SEQUENCE_TWO_TUPLE 180 +#define FOR_ITER_SET 64 +#define JUMP_BACKWARD_QUICK 65 +#define LOAD_ATTR_ADAPTIVE 66 +#define LOAD_ATTR_CLASS 67 +#define LOAD_ATTR_INSTANCE_VALUE 72 +#define LOAD_ATTR_MODULE 73 +#define LOAD_ATTR_PROPERTY 76 +#define LOAD_ATTR_SLOT 77 +#define LOAD_ATTR_WITH_HINT 78 +#define LOAD_ATTR_METHOD_LAZY_DICT 79 +#define LOAD_ATTR_METHOD_NO_DICT 80 +#define LOAD_ATTR_METHOD_WITH_DICT 81 +#define LOAD_ATTR_METHOD_WITH_VALUES 86 +#define LOAD_CONST__LOAD_FAST 113 +#define LOAD_FAST__LOAD_CONST 121 +#define LOAD_FAST__LOAD_FAST 141 +#define LOAD_GLOBAL_ADAPTIVE 143 +#define LOAD_GLOBAL_BUILTIN 153 +#define LOAD_GLOBAL_MODULE 154 +#define RESUME_QUICK 158 +#define STORE_ATTR_ADAPTIVE 159 +#define STORE_ATTR_INSTANCE_VALUE 160 +#define STORE_ATTR_SLOT 161 +#define STORE_ATTR_WITH_HINT 166 +#define STORE_FAST__LOAD_FAST 167 +#define STORE_FAST__STORE_FAST 168 +#define STORE_SUBSCR_ADAPTIVE 169 +#define STORE_SUBSCR_DICT 170 +#define STORE_SUBSCR_LIST_INT 177 +#define UNPACK_SEQUENCE_ADAPTIVE 178 +#define UNPACK_SEQUENCE_LIST 179 +#define UNPACK_SEQUENCE_TUPLE 180 +#define UNPACK_SEQUENCE_TWO_TUPLE 181 #define DO_TRACING 255 #define HAS_CONST(op) (false\ diff --git a/Lib/opcode.py b/Lib/opcode.py index f515aaa9fc8ddc..353f74b6183468 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -282,6 +282,7 @@ def jabs_op(name, op): "FOR_ITER_ADAPTIVE", "FOR_ITER_LIST", "FOR_ITER_RANGE", + "FOR_ITER_SET", ], "JUMP_BACKWARD": [ "JUMP_BACKWARD_QUICK", diff --git a/Makefile.pre.in b/Makefile.pre.in index 6448785c28070e..dd0dde622596ae 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1631,6 +1631,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/internal/pycore_range.h \ $(srcdir)/Include/internal/pycore_runtime.h \ $(srcdir)/Include/internal/pycore_runtime_init.h \ + $(srcdir)/Include/internal/pycore_set.h \ $(srcdir)/Include/internal/pycore_signal.h \ $(srcdir)/Include/internal/pycore_sliceobject.h \ $(srcdir)/Include/internal/pycore_strhex.h \ diff --git a/Objects/setobject.c b/Objects/setobject.c index dd55a943010ab8..47df01409bc265 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -32,12 +32,12 @@ */ #include "Python.h" +#include "pycore_set.h" // struct _PySetIterObject #include "pycore_object.h" // _PyObject_GC_UNTRACK() #include // offsetof() /* Object used as dummy key to fill deleted entries */ static PyObject _dummy_struct; - #define dummy (&_dummy_struct) @@ -730,16 +730,8 @@ frozenset_hash(PyObject *self) /***** Set iterator type ***********************************************/ -typedef struct { - PyObject_HEAD - PySetObject *si_set; /* Set to NULL when iterator is exhausted */ - Py_ssize_t si_used; - Py_ssize_t si_pos; - Py_ssize_t len; -} setiterobject; - static void -setiter_dealloc(setiterobject *si) +setiter_dealloc(_PySetIterObject *si) { /* bpo-31095: UnTrack is needed before calling any callbacks */ _PyObject_GC_UNTRACK(si); @@ -748,14 +740,14 @@ setiter_dealloc(setiterobject *si) } static int -setiter_traverse(setiterobject *si, visitproc visit, void *arg) +setiter_traverse(_PySetIterObject *si, visitproc visit, void *arg) { Py_VISIT(si->si_set); return 0; } static PyObject * -setiter_len(setiterobject *si, PyObject *Py_UNUSED(ignored)) +setiter_len(_PySetIterObject *si, PyObject *Py_UNUSED(ignored)) { Py_ssize_t len = 0; if (si->si_set != NULL && si->si_used == si->si_set->used) @@ -763,15 +755,15 @@ setiter_len(setiterobject *si, PyObject *Py_UNUSED(ignored)) return PyLong_FromSsize_t(len); } -PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); +static PyObject *setiter_iternext(_PySetIterObject *si); -static PyObject *setiter_iternext(setiterobject *si); +PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); static PyObject * -setiter_reduce(setiterobject *si, PyObject *Py_UNUSED(ignored)) +setiter_reduce(_PySetIterObject *si, PyObject *Py_UNUSED(ignored)) { /* copy the iterator state */ - setiterobject tmp = *si; + _PySetIterObject tmp = *si; Py_XINCREF(tmp.si_set); /* iterate the temporary into a list */ @@ -791,48 +783,60 @@ static PyMethodDef setiter_methods[] = { {NULL, NULL} /* sentinel */ }; -static PyObject *setiter_iternext(setiterobject *si) +int _PySetIter_GetNext(_PySetIterObject *si, PyObject **stack) { - PyObject *key; + assert(Py_IS_TYPE((PyObject *)si, &PySetIter_Type)); Py_ssize_t i, mask; setentry *entry; PySetObject *so = si->si_set; - if (so == NULL) - return NULL; + if (so == NULL) { + return 0; + } assert (PyAnySet_Check(so)); if (si->si_used != so->used) { PyErr_SetString(PyExc_RuntimeError, "Set changed size during iteration"); si->si_used = -1; /* Make this state sticky */ - return NULL; + return -1; } i = si->si_pos; assert(i>=0); entry = so->table; mask = so->mask; - while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy)) + while (i <= mask && (entry[i].key == NULL || entry[i].key == dummy)) { i++; + } si->si_pos = i+1; - if (i > mask) + if (i > mask) { goto fail; + } si->len--; - key = entry[i].key; - Py_INCREF(key); - return key; - + stack[0] = entry[i].key; + Py_INCREF(stack[0]); + return 1; fail: si->si_set = NULL; Py_DECREF(so); - return NULL; + return 0; +} + +static PyObject *setiter_iternext(_PySetIterObject *si) { + PyObject *key = NULL; + PyObject *stack[1]; + int err = _PySetIter_GetNext(si, stack); + if (err <= 0) { + return NULL; + } + return stack[0]; } PyTypeObject PySetIter_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "set_iterator", /* tp_name */ - sizeof(setiterobject), /* tp_basicsize */ + sizeof(_PySetIterObject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor)setiter_dealloc, /* tp_dealloc */ @@ -865,7 +869,7 @@ PyTypeObject PySetIter_Type = { static PyObject * set_iter(PySetObject *so) { - setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type); + _PySetIterObject *si = PyObject_GC_New(_PySetIterObject, &PySetIter_Type); if (si == NULL) return NULL; Py_INCREF(so); diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 09acce9d0c894a..da624d8f2031f1 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -242,6 +242,7 @@ + diff --git a/Python/ceval.c b/Python/ceval.c index 47dd1008c35ced..7cbcdb3e9b6eb4 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -23,6 +23,7 @@ #include "pycore_pymem.h" // _PyMem_IsPtrFreed() #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_range.h" // _PyRangeIterObject +#include "pycore_set.h" // _PySetIterObject() #include "pycore_sysmodule.h" // _PySys_Audit() #include "pycore_tuple.h" // _PyTuple_ITEMS() #include "pycore_emscripten_signal.h" // _Py_CHECK_EMSCRIPTEN_SIGNALS @@ -4488,6 +4489,25 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int goto iterator_exhausted_no_error; } + TARGET(FOR_ITER_SET) { + assert(cframe.use_tracing == 0); + _PySetIterObject *it = (_PySetIterObject *)TOP(); + DEOPT_IF(Py_TYPE(it) != &PySetIter_Type, FOR_ITER); + STAT_INC(FOR_ITER, hit); + int res = _PySetIter_GetNext(it, stack_pointer); + if (res > 0) { + STACK_GROW(1); + JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER); + NOTRACE_DISPATCH(); + } + else if (res == 0) { + goto iterator_exhausted_no_error; + } + else { + goto error; + } + } + TARGET(FOR_ITER_RANGE) { assert(cframe.use_tracing == 0); _PyRangeIterObject *r = (_PyRangeIterObject *)TOP(); diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index 8a6f1cdbbbb62f..fc2ee608dc5741 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -63,29 +63,29 @@ static void *opcode_targets[256] = { &&TARGET_DELETE_SUBSCR, &&TARGET_FOR_ITER_LIST, &&TARGET_FOR_ITER_RANGE, + &&TARGET_FOR_ITER_SET, &&TARGET_JUMP_BACKWARD_QUICK, &&TARGET_LOAD_ATTR_ADAPTIVE, &&TARGET_LOAD_ATTR_CLASS, - &&TARGET_LOAD_ATTR_INSTANCE_VALUE, &&TARGET_GET_ITER, &&TARGET_GET_YIELD_FROM_ITER, &&TARGET_PRINT_EXPR, &&TARGET_LOAD_BUILD_CLASS, + &&TARGET_LOAD_ATTR_INSTANCE_VALUE, &&TARGET_LOAD_ATTR_MODULE, - &&TARGET_LOAD_ATTR_PROPERTY, &&TARGET_LOAD_ASSERTION_ERROR, &&TARGET_RETURN_GENERATOR, + &&TARGET_LOAD_ATTR_PROPERTY, &&TARGET_LOAD_ATTR_SLOT, &&TARGET_LOAD_ATTR_WITH_HINT, &&TARGET_LOAD_ATTR_METHOD_LAZY_DICT, &&TARGET_LOAD_ATTR_METHOD_NO_DICT, &&TARGET_LOAD_ATTR_METHOD_WITH_DICT, - &&TARGET_LOAD_ATTR_METHOD_WITH_VALUES, &&TARGET_LIST_TO_TUPLE, &&TARGET_RETURN_VALUE, &&TARGET_IMPORT_STAR, &&TARGET_SETUP_ANNOTATIONS, - &&TARGET_LOAD_CONST__LOAD_FAST, + &&TARGET_LOAD_ATTR_METHOD_WITH_VALUES, &&TARGET_ASYNC_GEN_WRAP, &&TARGET_PREP_RERAISE_STAR, &&TARGET_POP_EXCEPT, @@ -112,7 +112,7 @@ static void *opcode_targets[256] = { &&TARGET_JUMP_FORWARD, &&TARGET_JUMP_IF_FALSE_OR_POP, &&TARGET_JUMP_IF_TRUE_OR_POP, - &&TARGET_LOAD_FAST__LOAD_CONST, + &&TARGET_LOAD_CONST__LOAD_FAST, &&TARGET_POP_JUMP_FORWARD_IF_FALSE, &&TARGET_POP_JUMP_FORWARD_IF_TRUE, &&TARGET_LOAD_GLOBAL, @@ -120,7 +120,7 @@ static void *opcode_targets[256] = { &&TARGET_CONTAINS_OP, &&TARGET_RERAISE, &&TARGET_COPY, - &&TARGET_LOAD_FAST__LOAD_FAST, + &&TARGET_LOAD_FAST__LOAD_CONST, &&TARGET_BINARY_OP, &&TARGET_SEND, &&TARGET_LOAD_FAST, @@ -140,9 +140,9 @@ static void *opcode_targets[256] = { &&TARGET_STORE_DEREF, &&TARGET_DELETE_DEREF, &&TARGET_JUMP_BACKWARD, - &&TARGET_LOAD_GLOBAL_ADAPTIVE, + &&TARGET_LOAD_FAST__LOAD_FAST, &&TARGET_CALL_FUNCTION_EX, - &&TARGET_LOAD_GLOBAL_BUILTIN, + &&TARGET_LOAD_GLOBAL_ADAPTIVE, &&TARGET_EXTENDED_ARG, &&TARGET_LIST_APPEND, &&TARGET_SET_ADD, @@ -152,30 +152,31 @@ static void *opcode_targets[256] = { &&TARGET_YIELD_VALUE, &&TARGET_RESUME, &&TARGET_MATCH_CLASS, + &&TARGET_LOAD_GLOBAL_BUILTIN, &&TARGET_LOAD_GLOBAL_MODULE, - &&TARGET_RESUME_QUICK, &&TARGET_FORMAT_VALUE, &&TARGET_BUILD_CONST_KEY_MAP, &&TARGET_BUILD_STRING, + &&TARGET_RESUME_QUICK, &&TARGET_STORE_ATTR_ADAPTIVE, &&TARGET_STORE_ATTR_INSTANCE_VALUE, &&TARGET_STORE_ATTR_SLOT, - &&TARGET_STORE_ATTR_WITH_HINT, &&TARGET_LIST_EXTEND, &&TARGET_SET_UPDATE, &&TARGET_DICT_MERGE, &&TARGET_DICT_UPDATE, + &&TARGET_STORE_ATTR_WITH_HINT, &&TARGET_STORE_FAST__LOAD_FAST, &&TARGET_STORE_FAST__STORE_FAST, &&TARGET_STORE_SUBSCR_ADAPTIVE, &&TARGET_STORE_SUBSCR_DICT, - &&TARGET_STORE_SUBSCR_LIST_INT, &&TARGET_CALL, &&TARGET_KW_NAMES, &&TARGET_POP_JUMP_BACKWARD_IF_NOT_NONE, &&TARGET_POP_JUMP_BACKWARD_IF_NONE, &&TARGET_POP_JUMP_BACKWARD_IF_FALSE, &&TARGET_POP_JUMP_BACKWARD_IF_TRUE, + &&TARGET_STORE_SUBSCR_LIST_INT, &&TARGET_UNPACK_SEQUENCE_ADAPTIVE, &&TARGET_UNPACK_SEQUENCE_LIST, &&TARGET_UNPACK_SEQUENCE_TUPLE, @@ -253,6 +254,5 @@ static void *opcode_targets[256] = { &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, - &&_unknown_opcode, &&TARGET_DO_TRACING }; diff --git a/Python/specialize.c b/Python/specialize.c index 948fb328695bb9..f2d5fe07f23861 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -2124,6 +2124,10 @@ _Py_Specialize_ForIter(PyObject *iter, _Py_CODEUNIT *instr) _Py_SET_OPCODE(*instr, FOR_ITER_RANGE); goto success; } + else if (tp == &PySetIter_Type) { + _Py_SET_OPCODE(*instr, FOR_ITER_SET); + goto success; + } else { SPECIALIZATION_FAIL(FOR_ITER, _PySpecialization_ClassifyIterator(iter)); From dba84eb9785fcc0db45dbaca85db4278679f3f1a Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Wed, 22 Jun 2022 17:15:46 +0900 Subject: [PATCH 2/5] nit --- Objects/setobject.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Objects/setobject.c b/Objects/setobject.c index 47df01409bc265..27cc00d44775bb 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -38,6 +38,7 @@ /* Object used as dummy key to fill deleted entries */ static PyObject _dummy_struct; + #define dummy (&_dummy_struct) From e8577bf4f46a5d2e0e3e015c1541a9eac06147a6 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Wed, 22 Jun 2022 17:57:14 +0900 Subject: [PATCH 3/5] Remove unused variable --- Objects/setobject.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Objects/setobject.c b/Objects/setobject.c index 27cc00d44775bb..2191a11c07c695 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -825,7 +825,6 @@ int _PySetIter_GetNext(_PySetIterObject *si, PyObject **stack) } static PyObject *setiter_iternext(_PySetIterObject *si) { - PyObject *key = NULL; PyObject *stack[1]; int err = _PySetIter_GetNext(si, stack); if (err <= 0) { From 1f7f882863069f577782240a0ba892665ef1d405 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Wed, 22 Jun 2022 18:23:11 +0900 Subject: [PATCH 4/5] Fix comment --- Include/internal/pycore_set.h | 2 ++ Objects/setobject.c | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Include/internal/pycore_set.h b/Include/internal/pycore_set.h index f67e41b67b1692..7e1327580c2f5b 100644 --- a/Include/internal/pycore_set.h +++ b/Include/internal/pycore_set.h @@ -8,6 +8,8 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +/***** Set iterator type ***********************************************/ + typedef struct { PyObject_HEAD PySetObject *si_set; /* Set to NULL when iterator is exhausted */ diff --git a/Objects/setobject.c b/Objects/setobject.c index 2191a11c07c695..2c8f535d8750ed 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -729,8 +729,6 @@ frozenset_hash(PyObject *self) return hash; } -/***** Set iterator type ***********************************************/ - static void setiter_dealloc(_PySetIterObject *si) { From f7f7305e20be00a5581d8b3b13237b87914d14c1 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Wed, 22 Jun 2022 18:33:08 +0900 Subject: [PATCH 5/5] Use C99 designated initializer --- Objects/setobject.c | 38 +++++++++----------------------------- 1 file changed, 9 insertions(+), 29 deletions(-) diff --git a/Objects/setobject.c b/Objects/setobject.c index 2c8f535d8750ed..7517666f53a3d4 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -833,35 +833,15 @@ static PyObject *setiter_iternext(_PySetIterObject *si) { PyTypeObject PySetIter_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) - "set_iterator", /* tp_name */ - sizeof(_PySetIterObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)setiter_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)setiter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)setiter_iternext, /* tp_iternext */ - setiter_methods, /* tp_methods */ - 0, + .tp_name = "set_iterator", + .tp_basicsize = sizeof(_PySetIterObject), + .tp_dealloc = (destructor)setiter_dealloc, + .tp_getattro = PyObject_GenericGetAttr, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .tp_traverse = (traverseproc)setiter_traverse, + .tp_iter = PyObject_SelfIter, + .tp_iternext = (iternextfunc)setiter_iternext, + .tp_methods = setiter_methods, }; static PyObject *