Skip to content

Commit 5e5acd2

Browse files
gh-100227: Move next_keys_version to PyInterpreterState (gh-102335)
#100227
1 parent 66ff374 commit 5e5acd2

File tree

5 files changed

+23
-13
lines changed

5 files changed

+23
-13
lines changed

Include/internal/pycore_dict.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ extern PyObject *_PyDict_FromKeys(PyObject *, PyObject *, PyObject *);
3737

3838
/* Gets a version number unique to the current state of the keys of dict, if possible.
3939
* Returns the version number, or zero if it was not possible to get a version number. */
40-
extern uint32_t _PyDictKeys_GetVersionForCurrentState(PyDictKeysObject *dictkeys);
40+
extern uint32_t _PyDictKeys_GetVersionForCurrentState(
41+
PyInterpreterState *interp, PyDictKeysObject *dictkeys);
4142

4243
extern size_t _PyDict_KeysSize(PyDictKeysObject *keys);
4344

Include/internal/pycore_dict_state.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ struct _Py_dict_runtime_state {
1414
* It is incremented each time that a dictionary is created and each
1515
* time that a dictionary is modified. */
1616
uint64_t global_version;
17-
uint32_t next_keys_version;
1817
};
1918

2019

@@ -30,13 +29,16 @@ struct _Py_dict_runtime_state {
3029
#define DICT_MAX_WATCHERS 8
3130

3231
struct _Py_dict_state {
32+
uint32_t next_keys_version;
33+
3334
#if PyDict_MAXFREELIST > 0
3435
/* Dictionary reuse scheme to save calls to malloc and free */
3536
PyDictObject *free_list[PyDict_MAXFREELIST];
3637
PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST];
3738
int numfree;
3839
int keys_numfree;
3940
#endif
41+
4042
PyDict_WatchCallback watchers[DICT_MAX_WATCHERS];
4143
};
4244

Include/internal/pycore_runtime_init.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,6 @@ extern PyTypeObject _PyExc_MemoryError;
6565
.float_format = _py_float_format_unknown, \
6666
.double_format = _py_float_format_unknown, \
6767
}, \
68-
.dict_state = { \
69-
.next_keys_version = 2, \
70-
}, \
7168
.types = { \
7269
.next_version_tag = 1, \
7370
}, \
@@ -113,6 +110,9 @@ extern PyTypeObject _PyExc_MemoryError;
113110
}, \
114111
}, \
115112
.dtoa = _dtoa_state_INIT(&(INTERP)), \
113+
.dict_state = { \
114+
.next_keys_version = 2, \
115+
}, \
116116
.func_state = { \
117117
.next_version = 1, \
118118
}, \

Objects/dictobject.c

+4-3
Original file line numberDiff line numberDiff line change
@@ -5655,15 +5655,16 @@ _PyDictKeys_DecRef(PyDictKeysObject *keys)
56555655
dictkeys_decref(keys);
56565656
}
56575657

5658-
uint32_t _PyDictKeys_GetVersionForCurrentState(PyDictKeysObject *dictkeys)
5658+
uint32_t _PyDictKeys_GetVersionForCurrentState(PyInterpreterState *interp,
5659+
PyDictKeysObject *dictkeys)
56595660
{
56605661
if (dictkeys->dk_version != 0) {
56615662
return dictkeys->dk_version;
56625663
}
5663-
if (_PyRuntime.dict_state.next_keys_version == 0) {
5664+
if (interp->dict_state.next_keys_version == 0) {
56645665
return 0;
56655666
}
5666-
uint32_t v = _PyRuntime.dict_state.next_keys_version++;
5667+
uint32_t v = interp->dict_state.next_keys_version++;
56675668
dictkeys->dk_version = v;
56685669
return v;
56695670
}

Python/specialize.c

+11-5
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,8 @@ specialize_module_load_attr(
512512
SPEC_FAIL_OUT_OF_RANGE);
513513
return -1;
514514
}
515-
uint32_t keys_version = _PyDictKeys_GetVersionForCurrentState(dict->ma_keys);
515+
uint32_t keys_version = _PyDictKeys_GetVersionForCurrentState(
516+
_PyInterpreterState_GET(), dict->ma_keys);
516517
if (keys_version == 0) {
517518
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_VERSIONS);
518519
return -1;
@@ -1063,7 +1064,8 @@ PyObject *descr, DescriptorClassification kind)
10631064
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_SHADOWED);
10641065
return 0;
10651066
}
1066-
uint32_t keys_version = _PyDictKeys_GetVersionForCurrentState(keys);
1067+
uint32_t keys_version = _PyDictKeys_GetVersionForCurrentState(
1068+
_PyInterpreterState_GET(), keys);
10671069
if (keys_version == 0) {
10681070
SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_VERSIONS);
10691071
return 0;
@@ -1134,12 +1136,14 @@ _Py_Specialize_LoadGlobal(
11341136
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_EXPECTED_ERROR);
11351137
goto fail;
11361138
}
1139+
PyInterpreterState *interp = _PyInterpreterState_GET();
11371140
if (index != DKIX_EMPTY) {
11381141
if (index != (uint16_t)index) {
11391142
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_RANGE);
11401143
goto fail;
11411144
}
1142-
uint32_t keys_version = _PyDictKeys_GetVersionForCurrentState(globals_keys);
1145+
uint32_t keys_version = _PyDictKeys_GetVersionForCurrentState(
1146+
interp, globals_keys);
11431147
if (keys_version == 0) {
11441148
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_VERSIONS);
11451149
goto fail;
@@ -1167,12 +1171,14 @@ _Py_Specialize_LoadGlobal(
11671171
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_RANGE);
11681172
goto fail;
11691173
}
1170-
uint32_t globals_version = _PyDictKeys_GetVersionForCurrentState(globals_keys);
1174+
uint32_t globals_version = _PyDictKeys_GetVersionForCurrentState(
1175+
interp, globals_keys);
11711176
if (globals_version == 0) {
11721177
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_VERSIONS);
11731178
goto fail;
11741179
}
1175-
uint32_t builtins_version = _PyDictKeys_GetVersionForCurrentState(builtin_keys);
1180+
uint32_t builtins_version = _PyDictKeys_GetVersionForCurrentState(
1181+
interp, builtin_keys);
11761182
if (builtins_version == 0) {
11771183
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_VERSIONS);
11781184
goto fail;

0 commit comments

Comments
 (0)