mirror of https://github.com/python/cpython
GH-113462: Limit the number of versions that a single class can use. (GH-114900)
This commit is contained in:
parent
87cd20a567
commit
992446dd5b
|
@ -229,6 +229,7 @@ struct _typeobject {
|
||||||
|
|
||||||
/* bitset of which type-watchers care about this type */
|
/* bitset of which type-watchers care about this type */
|
||||||
unsigned char tp_watched;
|
unsigned char tp_watched;
|
||||||
|
uint16_t tp_versions_used;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This struct is used by the specializer
|
/* This struct is used by the specializer
|
||||||
|
|
|
@ -79,6 +79,19 @@ class TypeCacheTests(unittest.TestCase):
|
||||||
|
|
||||||
_clear_type_cache()
|
_clear_type_cache()
|
||||||
|
|
||||||
|
def test_per_class_limit(self):
|
||||||
|
class C:
|
||||||
|
x = 0
|
||||||
|
|
||||||
|
type_assign_version(C)
|
||||||
|
orig_version = type_get_version(C)
|
||||||
|
for i in range(1001):
|
||||||
|
C.x = i
|
||||||
|
type_assign_version(C)
|
||||||
|
|
||||||
|
new_version = type_get_version(C)
|
||||||
|
self.assertEqual(new_version, 0)
|
||||||
|
|
||||||
|
|
||||||
@support.cpython_only
|
@support.cpython_only
|
||||||
class TypeCacheWithSpecializationTests(unittest.TestCase):
|
class TypeCacheWithSpecializationTests(unittest.TestCase):
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Limit the number of versions that a single class can use. Prevents a few
|
||||||
|
wayward classes using up all the version numbers.
|
|
@ -908,6 +908,8 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MAX_VERSIONS_PER_CLASS 1000
|
||||||
|
|
||||||
static int
|
static int
|
||||||
assign_version_tag(PyInterpreterState *interp, PyTypeObject *type)
|
assign_version_tag(PyInterpreterState *interp, PyTypeObject *type)
|
||||||
{
|
{
|
||||||
|
@ -922,7 +924,10 @@ assign_version_tag(PyInterpreterState *interp, PyTypeObject *type)
|
||||||
if (!_PyType_HasFeature(type, Py_TPFLAGS_READY)) {
|
if (!_PyType_HasFeature(type, Py_TPFLAGS_READY)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (type->tp_versions_used >= MAX_VERSIONS_PER_CLASS) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
type->tp_versions_used++;
|
||||||
if (type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) {
|
if (type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) {
|
||||||
/* static types */
|
/* static types */
|
||||||
if (NEXT_GLOBAL_VERSION_TAG > _Py_MAX_GLOBAL_TYPE_VERSION_TAG) {
|
if (NEXT_GLOBAL_VERSION_TAG > _Py_MAX_GLOBAL_TYPE_VERSION_TAG) {
|
||||||
|
|
Loading…
Reference in New Issue