8000 Fix buildbot errors: cache the type/class and compare that too · python/cpython@a12406b · GitHub
[go: up one dir, main page]

Skip to content

Commit a12406b

Browse files
Fix buildbot errors: cache the type/class and compare that too
1 parent ae2a520 commit a12406b

File tree

2 files changed

+13
-4
lines changed

2 files changed

+13
-4
lines changed

Python/ceval.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4289,7 +4289,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
42894289
_PyAdaptiveEntry *cache0 = &caches[0].adaptive;
42904290
_PyAttrCache *cache1 = &caches[-1].attr;
42914291
_PyObjectCache *cache2 = &caches[-2].obj;
4292+
_PyObjectCache *cache3 = &caches[-3].obj;
42924293

4294+
DEOPT_IF((PyObject *)self_cls != cache3->obj, LOAD_METHOD);
42934295
DEOPT_IF(self_cls->tp_version_tag != cache1->tp_version, LOAD_METHOD);
42944296
assert(cache1->dk_version_or_hint != 0);
42954297
assert(cache1->tp_version != 0);
@@ -4335,13 +4337,13 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
43354337
_PyAdaptiveEntry *cache0 = &caches[0].adaptive;
43364338
_PyAttrCache *cache1 = &caches[-1].attr;
43374339
_PyObjectCache *cache2 = &caches[-2].obj;
4340+
_PyObjectCache *cache3 = &caches[-3].obj;
43384341

43394342
PyObject *cls = TOP();
43404343
PyTypeObject *cls_type = Py_TYPE(cls);
43414344
assert(cls_type->tp_dictoffset > 0);
43424345
PyObject *dict = *(PyObject **) ((char *)cls + cls_type->tp_dictoffset);
4343-
DEOPT_IF(((PyDictObject *)dict)->ma_keys->dk_version !=
4344-
cache1->dk_version_or_hint, LOAD_METHOD);
4346+
DEOPT_IF(cls != cache3->obj, LOAD_METHOD);
43454347
DEOPT_IF(((PyTypeObject *)cls)->tp_version_tag != cache1->tp_version,
43464348
LOAD_METHOD);
43474349

Python/specialize.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ static uint8_t adaptive_opcodes[256] = {
233233
static uint8_t cache_requirements[256] = {
234234
[LOAD_ATTR] = 2, /* _PyAdaptiveEntry and _PyAttrCache */
235235
[LOAD_GLOBAL] = 2, /* _PyAdaptiveEntry and _PyLoadGlobalCache */
236-
[LOAD_METHOD] = 3, /* _PyAdaptiveEntry, _PyAttrCache and _PyObjectCache */
236+
[LOAD_METHOD] = 4, /* _PyAdaptiveEntry, _PyAttrCache and 2 _PyObjectCache */
237237
[BINARY_SUBSCR] = 0,
238238
[STORE_ATTR] = 2, /* _PyAdaptiveEntry and _PyAttrCache */
239239
};
@@ -817,6 +817,7 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name,
817817
_PyAdaptiveEntry *cache0 = &cache->adaptive;
818818
_PyAttrCache *cache1 = &cache[-1].attr;
819819
_PyObjectCache *cache2 = &cache[-2].obj;
820+
_PyObjectCache *cache3 = &cache[-3].obj;
820821

821822
PyTypeObject *owner_cls = Py_TYPE(owner);
822823
if (PyModule_CheckExact(owner)) {
@@ -851,6 +852,10 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name,
851852
int owner_is_class = PyType_Check(owner);
852853
owner_cls = owner_is_class ? (PyTypeObject *)owner : owner_cls;
853854

855+
if ((owner_cls->tp_flags & Py_TPFLAGS_VALID_VERSION_TAG) == 0) {
856+
SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_OUT_OF_RANGE);
857+
goto fail;
858+
}
854859
PyObject *descr = NULL;
855860
DesciptorClassification kind = 0;
856861
kind = analyze_descriptor(owner_cls, name, &descr, 0);
@@ -875,8 +880,9 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name,
875880
assert(kind == METHOD);
876881
// If o.__dict__ changes, the method might be found in o.__dict__
877882
// instead of old type lookup. So record o.__dict__'s keys.
883+
// Not required for class methods -- tp_version_tag is enough for those.
878884
uint32_t keys_version = UINT32_MAX;
879-
if (owner_has_dict) {
885+
if (owner_has_dict && !owner_is_class) {
880886
// _PyDictKeys_GetVersionForCurrentState isn't accurate for
881887
// custom dict subclasses at the moment.
882888
if (!PyDict_CheckExact(owner_dict)) {
@@ -923,6 +929,7 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name,
923929
* battle-tested.
924930
*/
925931
cache2->obj = descr;
932+
cache3->obj = (PyObject *)owner_cls; // borrowed - cache the type
926933
cache1->dk_version_or_hint = keys_version;
927934
*instr = _Py_MAKECODEUNIT(owner_is_class ? LOAD_METHOD_CLASS :
928935
LOAD_METHOD_CACHED, _Py_OPARG(*instr));

0 commit comments

Comments
 (0)
0