| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4496,6 +4496,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr | |||
| 4496 | 4496 | } | |
| 4497 | 4497 | ||
| 4498 | 4498 | TARGET(LOAD_METHOD_MODULE): { | |
| 4499 | + /* LOAD_METHOD, for module methods */ | ||
| 4499 | 4500 | assert(cframe.use_tracing == 0); | |
| 4500 | 4501 | PyObject *owner = TOP(); | |
| 4501 | 4502 | PyObject *res; | |
@@ -4515,15 +4516,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr | |||
| 4515 | 4516 | _PyObjectCache *cache2 = &caches[-2].obj; | |
| 4516 | 4517 | ||
| 4517 | 4518 | PyObject *cls = TOP(); | |
| 4518 | - PyTypeObject *cls_type = Py_TYPE(cls); | ||
| 4519 | - assert(cls_type->tp_dictoffset > 0); | ||
| 4520 | - PyObject *dict = *(PyObject **) ((char *)cls + cls_type->tp_dictoffset); | ||
| 4521 | - // Don't care if no dict -- tp_version_tag should catch anything wrong. | ||
| 4522 | - DEOPT_IF(dict != NULL && ((PyDictObject *)dict)->ma_keys->dk_version != | ||
| 4523 | - cache1->dk_version_or_hint, LOAD_METHOD); | ||
| 4519 | + DEOPT_IF(!PyType_Check(cls), LOAD_METHOD); | ||
| 4524 | 4520 | DEOPT_IF(((PyTypeObject *)cls)->tp_version_tag != cache1->tp_version, | |
| 4525 | 4521 | LOAD_METHOD); | |
| 4526 | - assert(cache1->dk_version_or_hint != 0); | ||
| 4527 | 4522 | assert(cache1->tp_version != 0); | |
| 4528 | 4523 | ||
| 4529 | 4524 | STAT_INC(LOAD_METHOD, hit); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -974,20 +974,19 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, | |||
| 974 | 974 | // Fall through. | |
| 975 | 975 | } // Else owner is maybe a builtin with no dict, or __slots__. Doesn't matter. | |
| 976 | 976 | ||
| 977 | - /* `descr` is borrowed. Just check tp_version_tag before accessing in case | ||
| 978 | - * it's deleted. This is safe for methods (even inherited ones from super | ||
| 979 | - * classes!) as long as tp_version_tag is validated for two main reasons: | ||
| 977 | + /* `descr` is borrowed. This is safe for methods (even inherited ones from | ||
| 978 | + * super classes!) as long as tp_version_tag is validated for two main reasons: | ||
| 980 | 979 | * | |
| 981 | 980 | * 1. The class will always hold a reference to the method so it will | |
| 982 | 981 | * usually not be GC-ed. Should it be deleted in Python, e.g. | |
| 983 | 982 | * `del obj.meth`, tp_version_tag will be invalidated, because of reason 2. | |
| 984 | 983 | * | |
| 985 | 984 | * 2. The pre-existing type method cache (MCACHE) uses the same principles | |
| 986 | - * of caching a borrowed descriptor. It does all the heavy lifting for us. | ||
| 987 | - * E.g. it invalidates on any MRO modification, on any type object | ||
| 988 | - * change along said MRO, etc. (see PyType_Modified usages in typeobject.c). | ||
| 989 | - * The type method cache has been working since Python 2.6 and it's | ||
| 990 | - * battle-tested. | ||
| 985 | + * of caching a borrowed descriptor. The MCACHE infrastructure does all the | ||
| 986 | + * heavy lifting for us. E.g. it invalidates tp_version_tag on any MRO | ||
| 987 | + * modification, on any type object change along said MRO, etc. (see | ||
| 988 | + * PyType_Modified usages in typeobject.c). The MCACHE has been | ||
| 989 | + * working since Python 2.6 and it's battle-tested. | ||
| 991 | 990 | */ | |
| 992 | 991 | cache2->obj = descr; | |
| 993 | 992 | cache1->dk_version_or_hint = keys_version; | |
| Back | FazBrowse Home | New Git URL |
0 commit comments