| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent f4d5332 commit b58875e
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -735,6 +735,13 @@ _PyThreadState_PushCStackRef(PyThreadState *tstate, _PyCStackRef *ref) | |||
| 735 | 735 | ref->ref = PyStackRef_NULL; | |
| 736 | 736 | } | |
| 737 | 737 | ||
| 738 | + static inline void | ||
| 739 | + _PyThreadState_PushCStackRefNew(PyThreadState *tstate, _PyCStackRef *ref, PyObject *obj) | ||
| 740 | + { | ||
| 741 | + _PyThreadState_PushCStackRef(tstate, ref); | ||
| 742 | + ref->ref = PyStackRef_FromPyObjectNew(obj); | ||
| 743 | + } | ||
| 744 | + | ||
| 738 | 745 | static inline void | |
| 739 | 746 | _PyThreadState_PopCStackRef(PyThreadState *tstate, _PyCStackRef *ref) | |
| 740 | 747 | { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -11820,18 +11820,16 @@ _super_lookup_descr(PyTypeObject *su_type, PyTypeObject *su_obj_type, PyObject * | |||
| 11820 | 11820 | PyObject *mro, *res; | |
| 11821 | 11821 | Py_ssize_t i, n; | |
| 11822 | 11822 | ||
| 11823 | - BEGIN_TYPE_LOCK(); | ||
| 11824 | 11823 | mro = lookup_tp_mro(su_obj_type); | |
| 11825 | - /* keep a strong reference to mro because su_obj_type->tp_mro can be | ||
| 11826 | - replaced during PyDict_GetItemRef(dict, name, &res) and because | ||
| 11827 | - another thread can modify it after we end the critical section | ||
| 11828 | - below */ | ||
| 11829 | - Py_XINCREF(mro); | ||
| 11830 | - END_TYPE_LOCK(); | ||
| 11831 | - | ||
| 11832 | 11824 | if (mro == NULL) | |
| 11833 | 11825 | return NULL; | |
| 11834 | 11826 | ||
| 11827 | + /* Keep a strong reference to mro because su_obj_type->tp_mro can be | ||
| 11828 | + replaced during PyDict_GetItemRef(dict, name, &res). */ | ||
| 11829 | + PyThreadState *tstate = _PyThreadState_GET(); | ||
| 11830 | + _PyCStackRef mro_ref; | ||
| 11831 | + _PyThreadState_PushCStackRefNew(tstate, &mro_ref, mro); | ||
| 11832 | + | ||
| 11835 | 11833 | assert(PyTuple_Check(mro)); | |
| 11836 | 11834 | n = PyTuple_GET_SIZE(mro); | |
| 11837 | 11835 | ||
@@ -11842,7 +11840,7 @@ _super_lookup_descr(PyTypeObject *su_type, PyTypeObject *su_obj_type, PyObject * | |||
| 11842 | 11840 | } | |
| 11843 | 11841 | i++; /* skip su->type (if any) */ | |
| 11844 | 11842 | if (i >= n) { | |
| 11845 | - Py_DECREF(mro); | ||
| 11843 | + _PyThreadState_PopCStackRef(tstate, &mro_ref); | ||
| 11846 | 11844 | return NULL; | |
| 11847 | 11845 | } | |
| 11848 | 11846 | ||
@@ -11853,13 +11851,13 @@ _super_lookup_descr(PyTypeObject *su_type, PyTypeObject *su_obj_type, PyObject * | |||
| 11853 | 11851 | ||
| 11854 | 11852 | if (PyDict_GetItemRef(dict, name, &res) != 0) { | |
| 11855 | 11853 | // found or error | |
| 11856 | - Py_DECREF(mro); | ||
| 11854 | + _PyThreadState_PopCStackRef(tstate, &mro_ref); | ||
| 11857 | 11855 | return res; | |
| 11858 | 11856 | } | |
| 11859 | 11857 | ||
| 11860 | 11858 | i++; | |
| 11861 | 11859 | } while (i < n); | |
| 11862 | - Py_DECREF(mro); | ||
| 11860 | + _PyThreadState_PopCStackRef(tstate, &mro_ref); | ||
| 11863 | 11861 | return NULL; | |
| 11864 | 11862 | } | |
| 11865 | 11863 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -201,6 +201,23 @@ def instantiate_dataclass(): | |||
| 201 | 201 | for _ in range(1000 * WORK_SCALE): | |
| 202 | 202 | obj = MyDataClass(x=1, y=2, z=3) | |
| 203 | 203 | ||
| 204 | + @register_benchmark | ||
| 205 | + def super_call(): | ||
| 206 | + # TODO: super() on the same class from multiple threads still doesn't | ||
| 207 | + # scale well, so use a class per-thread here for now. | ||
| 208 | + class Base: | ||
| 209 | + def method(self): | ||
| 210 | + return 1 | ||
| 211 | + | ||
| 212 | + class Derived(Base): | ||
| 213 | + def method(self): | ||
| 214 | + return super().method() | ||
| 215 | + | ||
| 216 | + obj = Derived() | ||
| 217 | + for _ in range(1000 * WORK_SCALE): | ||
| 218 | + obj.method() | ||
| 219 | + | ||
| 220 | + | ||
| 204 | 221 | def bench_one_thread(func): | |
| 205 | 222 | t0 = time.perf_counter_ns() | |
| 206 | 223 | func() | |
| Back | FazBrowse Home | New Git URL |
0 commit comments