Skip to content

Commit d27e388

Browse files
Fix for types with no dict
1 parent 020a326 commit d27e388

File tree

2 files changed

+9
-7
lines changed

2 files changed

+9
-7
lines changed

Python/ceval.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4409,11 +4409,14 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
44094409
PyTypeObject *cls_type = Py_TYPE(cls);
44104410
assert(cls_type->tp_dictoffset > 0);
44114411
PyObject *dict = *(PyObject **) ((char *)cls + cls_type->tp_dictoffset);
4412-
DEOPT_IF(((PyDictObject *)dict)->ma_keys->dk_version !=
4412+
// Don't care if no dict -- tp_version_tag should catch anything wrong.
4413+
DEOPT_IF(dict != NULL && ((PyDictObject *)dict)->ma_keys->dk_version !=
44134414
cache1->dk_version_or_hint, LOAD_METHOD);
44144415
DEOPT_IF(((PyTypeObject *)cls)->tp_version_tag != cache1->tp_version,
44154416
LOAD_METHOD);
4416-
4417+
assert(cache1->dk_version_or_hint != 0);
4418+
assert(cache1->tp_version != 0);
4419+
44174420
STAT_INC(LOAD_METHOD, hit);
44184421
record_cache_hit(cache0);
44194422
PyObject *res = cache2->obj;

Python/specialize.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -857,18 +857,17 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name,
857857
SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_OUT_OF_RANGE);
858858
goto fail;
859859
}
860-
// Technically this is fine for bound method calls, but slightly slower at
861-
// runtime to get dict. TODO: profile pyperformance and see if it's worth it
862-
// to slightly slow down the common case, so that we can specialize this
863-
// uncommon one.
860+
// Technically this is fine for bound method calls, but it's uncommon and
861+
// slightly slower at runtime to get dict.
864862
if (owner_cls->tp_dictoffset < 0) {
865863
SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_NEGATIVE_DICTOFFSET);
866864
goto fail;
867865
}
868866
PyObject **owner_dictptr = _PyObject_GetDictPtr(owner);
869867
int owner_has_dict = (owner_dictptr != NULL && *owner_dictptr != NULL);
870868
owner_dict = owner_has_dict ? (PyDictObject *)*owner_dictptr : NULL;
871-
Py_XINCREF(owner_dict); // make sure dict doesn't disappear halfway
869+
// Make sure dict doesn't get GC-ed halfway.
870+
Py_XINCREF(owner_dict);
872871
// Check for classmethods.
873872
int owner_is_class = PyType_Check(owner);
874873
owner_cls = owner_is_class ? (PyTypeObject *)owner : owner_cls;

0 commit comments

Comments
 (0)