Skip to content

Commit 16f15b2

Browse files
committed
Revert more changes.
These are not required as part of this PR and can be reviewed separately.
1 parent 0eb77da commit 16f15b2

File tree

1 file changed

+52
-76
lines changed

1 file changed

+52
-76
lines changed

Objects/typeobject.c

Lines changed: 52 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,14 +1156,6 @@ type_modified_unlocked(PyTypeObject *type)
11561156
}
11571157
}
11581158

1159-
set_version_unlocked(type, 0); /* 0 is not a valid version tag */
1160-
if (PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) {
1161-
// This field *must* be invalidated if the type is modified (see the
1162-
// comment on struct _specialization_cache):
1163-
FT_ATOMIC_STORE_PTR_RELAXED(
1164-
((PyHeapTypeObject *)type)->_spec_cache.getitem, NULL);
1165-
}
1166-
11671159
// Notify registered type watchers, if any
11681160
if (type->tp_watched) {
11691161
PyInterpreterState *interp = _PyInterpreterState_GET();
@@ -1185,6 +1177,14 @@ type_modified_unlocked(PyTypeObject *type)
11851177
bits >>= 1;
11861178
}
11871179
}
1180+
1181+
set_version_unlocked(type, 0); /* 0 is not a valid version tag */
1182+
if (PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) {
1183+
// This field *must* be invalidated if the type is modified (see the
1184+
// comment on struct _specialization_cache):
1185+
FT_ATOMIC_STORE_PTR_RELAXED(
1186+
((PyHeapTypeObject *)type)->_spec_cache.getitem, NULL);
1187+
}
11881188
}
11891189

11901190
void
@@ -1238,21 +1238,14 @@ type_mro_modified(PyTypeObject *type, PyObject *bases)
12381238
Called from mro_internal, which will subsequently be called on
12391239
each subclass when their mro is recursively updated.
12401240
*/
1241+
Py_ssize_t i, n;
1242+
12411243
ASSERT_TYPE_LOCK_HELD();
1242-
if (!Py_IS_TYPE(type, &PyType_Type)) {
1243-
unsigned int meta_version = Py_TYPE(type)->tp_version_tag;
1244-
// This can be re-entrant.
1245-
bool is_custom = has_custom_mro(type);
1246-
if (meta_version != Py_TYPE(type)->tp_version_tag) {
1247-
// metaclass changed during call of has_custom_mro()
1248-
goto clear;
1249-
}
1250-
if (is_custom) {
1251-
goto clear;
1252-
}
1244+
if (!Py_IS_TYPE(type, &PyType_Type) && has_custom_mro(type)) {
1245+
goto clear;
12531246
}
1254-
Py_ssize_t n = PyTuple_GET_SIZE(bases);
1255-
for (Py_ssize_t i = 0; i < n; i++) {
1247+
n = PyTuple_GET_SIZE(bases);
1248+
for (i = 0; i < n; i++) {
12561249
PyObject *b = PyTuple_GET_ITEM(bases, i);
12571250
PyTypeObject *cls = _PyType_CAST(b);
12581251

@@ -5771,22 +5764,12 @@ update_cache(struct type_cache_entry *entry, PyObject *name, unsigned int versio
57715764
return old_name;
57725765
}
57735766

5767+
#if Py_GIL_DISABLED
5768+
57745769
static void
5775-
maybe_update_cache(PyTypeObject *type, struct type_cache_entry *entry,
5776-
PyObject *name, unsigned int version_tag, PyObject *value)
5770+
update_cache_gil_disabled(struct type_cache_entry *entry, PyObject *name,
5771+
unsigned int version_tag, PyObject *value)
57775772
{
5778-
if (version_tag == 0) {
5779-
return; // 0 is not a valid version
5780-
}
5781-
// Calling find_name_in_mro() might cause the type version to change.
5782-
// For example, if a __hash__ or __eq__ method mutates the types.
5783-
// This case is expected to be rare but we check for it here and avoid
5784-
// replacing a valid cache entry with a known to be stale one.
5785-
if (FT_ATOMIC_LOAD_UINT_RELAXED(type->tp_version_tag) != version_tag) {
5786-
return; // version changed during lookup
5787-
}
5788-
PyObject *old_value;
5789-
#ifdef Py_GIL_DISABLED
57905773
_PySeqLock_LockWrite(&entry->sequence);
57915774

57925775
// update the entry
@@ -5798,16 +5781,16 @@ maybe_update_cache(PyTypeObject *type, struct type_cache_entry *entry,
57985781
return;
57995782
}
58005783

5801-
old_value = update_cache(entry, name, version_tag, value);
5784+
PyObject *old_value = update_cache(entry, name, version_tag, value);
58025785

58035786
// Then update sequence to the next valid value
58045787
_PySeqLock_UnlockWrite(&entry->sequence);
5805-
#else
5806-
old_value = update_cache(entry, name, version_tag, value);
5807-
#endif
5788+
58085789
Py_DECREF(old_value);
58095790
}
58105791

5792+
#endif
5793+
58115794
void
58125795
_PyTypes_AfterFork(void)
58135796
{
@@ -5825,22 +5808,23 @@ _PyTypes_AfterFork(void)
58255808
#endif
58265809
}
58275810

5828-
// Try to assign a new type version tag, return it if successful. Return 0
5829-
// if no version was assigned.
5830-
static unsigned int
5831-
type_assign_version(PyTypeObject *type)
5811+
/* Internal API to look for a name through the MRO.
5812+
This returns a strong reference, and doesn't set an exception!
5813+
If nonzero, version is set to the value of type->tp_version at the time of
5814+
the lookup.
5815+
*/
5816+
PyObject *
5817+
_PyType_LookupRefAndVersion(PyTypeObject *type, PyObject *name, unsigned int *version)
58325818
{
5833-
unsigned int version = type->tp_version_tag;
5834-
if (version == 0) {
5835-
PyInterpreterState *interp = _PyInterpreterState_GET();
5836-
if (assign_version_tag(interp, type)) {
5837-
version = type->tp_version_tag;
5838-
}
5839-
else {
5840-
version = 0;
5841-
}
5819+
_PyStackRef out;
5820+
unsigned int ver = _PyType_LookupStackRefAndVersion(type, name, &out);
5821+
if (version) {
5822+
*version = ver;
58425823
}
5843-
return version;
5824+
if (PyStackRef_IsNull(out)) {
5825+
return NULL;
5826+
}
5827+
return PyStackRef_AsPyObjectSteal(out);
58445828
}
58455829

58465830
unsigned int
@@ -5896,12 +5880,15 @@ _PyType_LookupStackRefAndVersion(PyTypeObject *type, PyObject *name, _PyStackRef
58965880

58975881
PyObject *res;
58985882
int error;
5899-
unsigned int assigned_version = 0; // 0 is not a valid version
5883+
PyInterpreterState *interp = _PyInterpreterState_GET();
5884+
int has_version = 0;
5885+
unsigned int assigned_version = 0;
59005886
BEGIN_TYPE_LOCK();
5887+
res = find_name_in_mro(type, name, &error);
59015888
if (MCACHE_CACHEABLE_NAME(name)) {
5902-
assigned_version = type_assign_version(type);
5889+
has_version = assign_version_tag(interp, type);
5890+
assigned_version = type->tp_version_tag;
59035891
}
5904-
res = find_name_in_mro(type, name, &error);
59055892
END_TYPE_LOCK();
59065893

59075894
/* Only put NULL results into cache if there was no error. */
@@ -5920,28 +5907,17 @@ _PyType_LookupStackRefAndVersion(PyTypeObject *type, PyObject *name, _PyStackRef
59205907
*out = PyStackRef_NULL;
59215908
return 0;
59225909
}
5923-
maybe_update_cache(type, entry, name, assigned_version, res);
5924-
*out = res ? PyStackRef_FromPyObjectSteal(res) : PyStackRef_NULL;
5925-
return assigned_version;
5926-
}
59275910

5928-
/* Internal API to look for a name through the MRO.
5929-
This returns a strong reference, and doesn't set an exception!
5930-
If nonzero, version is set to the value of type->tp_version at the time of
5931-
the lookup.
5932-
*/
5933-
PyObject *
5934-
_PyType_LookupRefAndVersion(PyTypeObject *type, PyObject *name, unsigned int *version)
5935-
{
5936-
_PyStackRef out;
5937-
unsigned int ver = _PyType_LookupStackRefAndVersion(type, name, &out);
5938-
if (version) {
5939-
*version = ver;
5940-
}
5941-
if (PyStackRef_IsNull(out)) {
5942-
return NULL;
5911+
if (has_version) {
5912+
#if Py_GIL_DISABLED
5913+
update_cache_gil_disabled(entry, name, assigned_version, res);
5914+
#else
5915+
PyObject *old_value = update_cache(entry, name, assigned_version, res);
5916+
Py_DECREF(old_value);
5917+
#endif
59435918
}
5944-
return PyStackRef_AsPyObjectSteal(out);
5919+
*out = res ? PyStackRef_FromPyObjectSteal(res) : PyStackRef_NULL;
5920+
return has_version ? assigned_version : 0;
59455921
}
59465922

59475923
/* Internal API to look for a name through the MRO.

0 commit comments

Comments
 (0)