mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	gh-81057: Move the global Dict-Related Versions to _PyRuntimeState (gh-99497)
We also move the global func version. https://github.com/python/cpython/issues/81057
This commit is contained in:
		
							parent
							
								
									8211cf5d28
								
							
						
					
					
						commit
						9db1e17c80
					
				
					 16 changed files with 89 additions and 48 deletions
				
			
		|  | @ -9,6 +9,9 @@ extern "C" { | ||||||
| #  error "this header requires Py_BUILD_CORE define" | #  error "this header requires Py_BUILD_CORE define" | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #include "pycore_dict_state.h" | ||||||
|  | #include "pycore_runtime.h"         // _PyRuntime | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| /* runtime lifecycle */ | /* runtime lifecycle */ | ||||||
| 
 | 
 | ||||||
|  | @ -17,25 +20,6 @@ extern void _PyDict_Fini(PyInterpreterState *interp); | ||||||
| 
 | 
 | ||||||
| /* other API */ | /* other API */ | ||||||
| 
 | 
 | ||||||
| #ifndef WITH_FREELISTS |  | ||||||
| // without freelists
 |  | ||||||
| #  define PyDict_MAXFREELIST 0 |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| #ifndef PyDict_MAXFREELIST |  | ||||||
| #  define PyDict_MAXFREELIST 80 |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| struct _Py_dict_state { |  | ||||||
| #if PyDict_MAXFREELIST > 0 |  | ||||||
|     /* Dictionary reuse scheme to save calls to malloc and free */ |  | ||||||
|     PyDictObject *free_list[PyDict_MAXFREELIST]; |  | ||||||
|     int numfree; |  | ||||||
|     PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST]; |  | ||||||
|     int keys_numfree; |  | ||||||
| #endif |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| typedef struct { | typedef struct { | ||||||
|     /* Cached hash code of me_key. */ |     /* Cached hash code of me_key. */ | ||||||
|     Py_hash_t me_hash; |     Py_hash_t me_hash; | ||||||
|  | @ -152,13 +136,11 @@ struct _dictvalues { | ||||||
|      (PyDictUnicodeEntry*)(&((int8_t*)((dk)->dk_indices))[(size_t)1 << (dk)->dk_log2_index_bytes])) |      (PyDictUnicodeEntry*)(&((int8_t*)((dk)->dk_indices))[(size_t)1 << (dk)->dk_log2_index_bytes])) | ||||||
| #define DK_IS_UNICODE(dk) ((dk)->dk_kind != DICT_KEYS_GENERAL) | #define DK_IS_UNICODE(dk) ((dk)->dk_kind != DICT_KEYS_GENERAL) | ||||||
| 
 | 
 | ||||||
| extern uint64_t _pydict_global_version; |  | ||||||
| 
 |  | ||||||
| #define DICT_MAX_WATCHERS 8 |  | ||||||
| #define DICT_VERSION_INCREMENT (1 << DICT_MAX_WATCHERS) | #define DICT_VERSION_INCREMENT (1 << DICT_MAX_WATCHERS) | ||||||
| #define DICT_VERSION_MASK (DICT_VERSION_INCREMENT - 1) | #define DICT_VERSION_MASK (DICT_VERSION_INCREMENT - 1) | ||||||
| 
 | 
 | ||||||
| #define DICT_NEXT_VERSION() (_pydict_global_version += DICT_VERSION_INCREMENT) | #define DICT_NEXT_VERSION() \ | ||||||
|  |     (_PyRuntime.dict_state.global_version += DICT_VERSION_INCREMENT) | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| _PyDict_SendEvent(int watcher_bits, | _PyDict_SendEvent(int watcher_bits, | ||||||
|  |  | ||||||
							
								
								
									
										47
									
								
								Include/internal/pycore_dict_state.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								Include/internal/pycore_dict_state.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,47 @@ | ||||||
|  | #ifndef Py_INTERNAL_DICT_STATE_H | ||||||
|  | #define Py_INTERNAL_DICT_STATE_H | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef Py_BUILD_CORE | ||||||
|  | #  error "this header requires Py_BUILD_CORE define" | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | struct _Py_dict_runtime_state { | ||||||
|  |     /*Global counter used to set ma_version_tag field of dictionary.
 | ||||||
|  |      * It is incremented each time that a dictionary is created and each | ||||||
|  |      * time that a dictionary is modified. */ | ||||||
|  |     uint64_t global_version; | ||||||
|  |     uint32_t next_keys_version; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifndef WITH_FREELISTS | ||||||
|  | // without freelists
 | ||||||
|  | #  define PyDict_MAXFREELIST 0 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef PyDict_MAXFREELIST | ||||||
|  | #  define PyDict_MAXFREELIST 80 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #define DICT_MAX_WATCHERS 8 | ||||||
|  | 
 | ||||||
|  | struct _Py_dict_state { | ||||||
|  | #if PyDict_MAXFREELIST > 0 | ||||||
|  |     /* Dictionary reuse scheme to save calls to malloc and free */ | ||||||
|  |     PyDictObject *free_list[PyDict_MAXFREELIST]; | ||||||
|  |     PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST]; | ||||||
|  |     int numfree; | ||||||
|  |     int keys_numfree; | ||||||
|  | #endif | ||||||
|  |     PyDict_WatchCallback watchers[DICT_MAX_WATCHERS]; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | #endif   /* !Py_INTERNAL_DICT_STATE_H */ | ||||||
|  | @ -8,6 +8,10 @@ extern "C" { | ||||||
| #  error "this header requires Py_BUILD_CORE define" | #  error "this header requires Py_BUILD_CORE define" | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | struct _py_func_runtime_state { | ||||||
|  |     uint32_t next_version; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| extern PyFunctionObject* _PyFunction_FromConstructor(PyFrameConstructor *constr); | extern PyFunctionObject* _PyFunction_FromConstructor(PyFrameConstructor *constr); | ||||||
| 
 | 
 | ||||||
| extern uint32_t _PyFunction_GetVersionForCurrentState(PyFunctionObject *func); | extern uint32_t _PyFunction_GetVersionForCurrentState(PyFunctionObject *func); | ||||||
|  |  | ||||||
|  | @ -14,7 +14,7 @@ extern "C" { | ||||||
| #include "pycore_ast_state.h"     // struct ast_state | #include "pycore_ast_state.h"     // struct ast_state | ||||||
| #include "pycore_code.h"          // struct callable_cache | #include "pycore_code.h"          // struct callable_cache | ||||||
| #include "pycore_context.h"       // struct _Py_context_state | #include "pycore_context.h"       // struct _Py_context_state | ||||||
| #include "pycore_dict.h"          // struct _Py_dict_state | #include "pycore_dict_state.h"    // struct _Py_dict_state | ||||||
| #include "pycore_exceptions.h"    // struct _Py_exc_state | #include "pycore_exceptions.h"    // struct _Py_exc_state | ||||||
| #include "pycore_floatobject.h"   // struct _Py_float_state | #include "pycore_floatobject.h"   // struct _Py_float_state | ||||||
| #include "pycore_genobject.h"     // struct _Py_async_gen_state | #include "pycore_genobject.h"     // struct _Py_async_gen_state | ||||||
|  | @ -171,8 +171,6 @@ struct _is { | ||||||
|     // Initialized to _PyEval_EvalFrameDefault().
 |     // Initialized to _PyEval_EvalFrameDefault().
 | ||||||
|     _PyFrameEvalFunction eval_frame; |     _PyFrameEvalFunction eval_frame; | ||||||
| 
 | 
 | ||||||
|     PyDict_WatchCallback dict_watchers[DICT_MAX_WATCHERS]; |  | ||||||
| 
 |  | ||||||
|     Py_ssize_t co_extra_user_count; |     Py_ssize_t co_extra_user_count; | ||||||
|     freefunc co_extra_freefuncs[MAX_CO_EXTRA_USERS]; |     freefunc co_extra_freefuncs[MAX_CO_EXTRA_USERS]; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -9,8 +9,10 @@ extern "C" { | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #include "pycore_atomic.h"          /* _Py_atomic_address */ | #include "pycore_atomic.h"          /* _Py_atomic_address */ | ||||||
|  | #include "pycore_dict_state.h"      // struct _Py_dict_runtime_state | ||||||
| #include "pycore_dtoa.h"            // struct _dtoa_runtime_state | #include "pycore_dtoa.h"            // struct _dtoa_runtime_state | ||||||
| #include "pycore_floatobject.h"     // struct _Py_float_runtime_state | #include "pycore_floatobject.h"     // struct _Py_float_runtime_state | ||||||
|  | #include "pycore_function.h"        // struct _func_runtime_state | ||||||
| #include "pycore_gil.h"             // struct _gil_runtime_state | #include "pycore_gil.h"             // struct _gil_runtime_state | ||||||
| #include "pycore_global_objects.h"  // struct _Py_global_objects | #include "pycore_global_objects.h"  // struct _Py_global_objects | ||||||
| #include "pycore_import.h"          // struct _import_runtime_state | #include "pycore_import.h"          // struct _import_runtime_state | ||||||
|  | @ -151,6 +153,8 @@ typedef struct pyruntimestate { | ||||||
| 
 | 
 | ||||||
|     struct _Py_float_runtime_state float_state; |     struct _Py_float_runtime_state float_state; | ||||||
|     struct _Py_unicode_runtime_state unicode_state; |     struct _Py_unicode_runtime_state unicode_state; | ||||||
|  |     struct _Py_dict_runtime_state dict_state; | ||||||
|  |     struct _py_func_runtime_state func_state; | ||||||
| 
 | 
 | ||||||
|     struct { |     struct { | ||||||
|         /* Used to set PyTypeObject.tp_version_tag */ |         /* Used to set PyTypeObject.tp_version_tag */ | ||||||
|  |  | ||||||
|  | @ -58,6 +58,12 @@ extern "C" { | ||||||
|             .float_format = _py_float_format_unknown, \ |             .float_format = _py_float_format_unknown, \ | ||||||
|             .double_format = _py_float_format_unknown, \ |             .double_format = _py_float_format_unknown, \ | ||||||
|         }, \ |         }, \ | ||||||
|  |         .dict_state = { \ | ||||||
|  |             .next_keys_version = 2, \ | ||||||
|  |         }, \ | ||||||
|  |         .func_state = { \ | ||||||
|  |             .next_version = 1, \ | ||||||
|  |         }, \ | ||||||
|         .types = { \ |         .types = { \ | ||||||
|             .next_version_tag = 1, \ |             .next_version_tag = 1, \ | ||||||
|         }, \ |         }, \ | ||||||
|  |  | ||||||
|  | @ -1627,6 +1627,7 @@ PYTHON_HEADERS= \ | ||||||
| 		$(srcdir)/Include/internal/pycore_condvar.h \ | 		$(srcdir)/Include/internal/pycore_condvar.h \ | ||||||
| 		$(srcdir)/Include/internal/pycore_context.h \ | 		$(srcdir)/Include/internal/pycore_context.h \ | ||||||
| 		$(srcdir)/Include/internal/pycore_dict.h \ | 		$(srcdir)/Include/internal/pycore_dict.h \ | ||||||
|  | 		$(srcdir)/Include/internal/pycore_dict_state.h \ | ||||||
| 		$(srcdir)/Include/internal/pycore_descrobject.h \ | 		$(srcdir)/Include/internal/pycore_descrobject.h \ | ||||||
| 		$(srcdir)/Include/internal/pycore_dtoa.h \ | 		$(srcdir)/Include/internal/pycore_dtoa.h \ | ||||||
| 		$(srcdir)/Include/internal/pycore_exceptions.h \ | 		$(srcdir)/Include/internal/pycore_exceptions.h \ | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| #include "Python.h" | #include "Python.h" | ||||||
| #include "pycore_call.h"          // _PyObject_CallNoArgs() | #include "pycore_call.h"          // _PyObject_CallNoArgs() | ||||||
|  | #include "pycore_dict.h"          // _PyDict_Pop_KnownHash() | ||||||
| #include "pycore_long.h"          // _PyLong_GetZero() | #include "pycore_long.h"          // _PyLong_GetZero() | ||||||
| #include "pycore_moduleobject.h"  // _PyModule_GetState() | #include "pycore_moduleobject.h"  // _PyModule_GetState() | ||||||
| #include "pycore_object.h"        // _PyObject_GC_TRACK | #include "pycore_object.h"        // _PyObject_GC_TRACK | ||||||
|  |  | ||||||
|  | @ -1,6 +1,7 @@ | ||||||
| #include "Python.h" | #include "Python.h" | ||||||
| #include "pycore_call.h"          // _PyObject_CallNoArgsTstate() | #include "pycore_call.h"          // _PyObject_CallNoArgsTstate() | ||||||
| #include "pycore_ceval.h"         // _Py_EnterRecursiveCallTstate() | #include "pycore_ceval.h"         // _Py_EnterRecursiveCallTstate() | ||||||
|  | #include "pycore_dict.h"          // _PyDict_FromItems() | ||||||
| #include "pycore_object.h"        // _PyCFunctionWithKeywords_TrampolineCall() | #include "pycore_object.h"        // _PyCFunctionWithKeywords_TrampolineCall() | ||||||
| #include "pycore_pyerrors.h"      // _PyErr_Occurred() | #include "pycore_pyerrors.h"      // _PyErr_Occurred() | ||||||
| #include "pycore_pystate.h"       // _PyThreadState_GET() | #include "pycore_pystate.h"       // _PyThreadState_GET() | ||||||
|  |  | ||||||
|  | @ -236,11 +236,6 @@ static int dictresize(PyDictObject *mp, uint8_t log_newsize, int unicode); | ||||||
| 
 | 
 | ||||||
| static PyObject* dict_iter(PyDictObject *dict); | static PyObject* dict_iter(PyDictObject *dict); | ||||||
| 
 | 
 | ||||||
| /*Global counter used to set ma_version_tag field of dictionary.
 |  | ||||||
|  * It is incremented each time that a dictionary is created and each |  | ||||||
|  * time that a dictionary is modified. */ |  | ||||||
| uint64_t _pydict_global_version = 0; |  | ||||||
| 
 |  | ||||||
| #include "clinic/dictobject.c.h" | #include "clinic/dictobject.c.h" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -5658,17 +5653,15 @@ _PyDictKeys_DecRef(PyDictKeysObject *keys) | ||||||
|     dictkeys_decref(keys); |     dictkeys_decref(keys); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static uint32_t next_dict_keys_version = 2; |  | ||||||
| 
 |  | ||||||
| uint32_t _PyDictKeys_GetVersionForCurrentState(PyDictKeysObject *dictkeys) | uint32_t _PyDictKeys_GetVersionForCurrentState(PyDictKeysObject *dictkeys) | ||||||
| { | { | ||||||
|     if (dictkeys->dk_version != 0) { |     if (dictkeys->dk_version != 0) { | ||||||
|         return dictkeys->dk_version; |         return dictkeys->dk_version; | ||||||
|     } |     } | ||||||
|     if (next_dict_keys_version == 0) { |     if (_PyRuntime.dict_state.next_keys_version == 0) { | ||||||
|         return 0; |         return 0; | ||||||
|     } |     } | ||||||
|     uint32_t v = next_dict_keys_version++; |     uint32_t v = _PyRuntime.dict_state.next_keys_version++; | ||||||
|     dictkeys->dk_version = v; |     dictkeys->dk_version = v; | ||||||
|     return v; |     return v; | ||||||
| } | } | ||||||
|  | @ -5680,7 +5673,7 @@ validate_watcher_id(PyInterpreterState *interp, int watcher_id) | ||||||
|         PyErr_Format(PyExc_ValueError, "Invalid dict watcher ID %d", watcher_id); |         PyErr_Format(PyExc_ValueError, "Invalid dict watcher ID %d", watcher_id); | ||||||
|         return -1; |         return -1; | ||||||
|     } |     } | ||||||
|     if (!interp->dict_watchers[watcher_id]) { |     if (!interp->dict_state.watchers[watcher_id]) { | ||||||
|         PyErr_Format(PyExc_ValueError, "No dict watcher set for ID %d", watcher_id); |         PyErr_Format(PyExc_ValueError, "No dict watcher set for ID %d", watcher_id); | ||||||
|         return -1; |         return -1; | ||||||
|     } |     } | ||||||
|  | @ -5723,8 +5716,8 @@ PyDict_AddWatcher(PyDict_WatchCallback callback) | ||||||
|     PyInterpreterState *interp = _PyInterpreterState_GET(); |     PyInterpreterState *interp = _PyInterpreterState_GET(); | ||||||
| 
 | 
 | ||||||
|     for (int i = 0; i < DICT_MAX_WATCHERS; i++) { |     for (int i = 0; i < DICT_MAX_WATCHERS; i++) { | ||||||
|         if (!interp->dict_watchers[i]) { |         if (!interp->dict_state.watchers[i]) { | ||||||
|             interp->dict_watchers[i] = callback; |             interp->dict_state.watchers[i] = callback; | ||||||
|             return i; |             return i; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | @ -5740,7 +5733,7 @@ PyDict_ClearWatcher(int watcher_id) | ||||||
|     if (validate_watcher_id(interp, watcher_id)) { |     if (validate_watcher_id(interp, watcher_id)) { | ||||||
|         return -1; |         return -1; | ||||||
|     } |     } | ||||||
|     interp->dict_watchers[watcher_id] = NULL; |     interp->dict_state.watchers[watcher_id] = NULL; | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -5754,7 +5747,7 @@ _PyDict_SendEvent(int watcher_bits, | ||||||
|     PyInterpreterState *interp = _PyInterpreterState_GET(); |     PyInterpreterState *interp = _PyInterpreterState_GET(); | ||||||
|     for (int i = 0; i < DICT_MAX_WATCHERS; i++) { |     for (int i = 0; i < DICT_MAX_WATCHERS; i++) { | ||||||
|         if (watcher_bits & 1) { |         if (watcher_bits & 1) { | ||||||
|             PyDict_WatchCallback cb = interp->dict_watchers[i]; |             PyDict_WatchCallback cb = interp->dict_state.watchers[i]; | ||||||
|             if (cb && (cb(event, (PyObject*)mp, key, value) < 0)) { |             if (cb && (cb(event, (PyObject*)mp, key, value) < 0)) { | ||||||
|                 // some dict modification paths (e.g. PyDict_Clear) can't raise, so we
 |                 // some dict modification paths (e.g. PyDict_Clear) can't raise, so we
 | ||||||
|                 // can't propagate exceptions from dict watchers.
 |                 // can't propagate exceptions from dict watchers.
 | ||||||
|  |  | ||||||
|  | @ -7,8 +7,6 @@ | ||||||
| #include "pycore_pyerrors.h"      // _PyErr_Occurred() | #include "pycore_pyerrors.h"      // _PyErr_Occurred() | ||||||
| #include "structmember.h"         // PyMemberDef | #include "structmember.h"         // PyMemberDef | ||||||
| 
 | 
 | ||||||
| static uint32_t next_func_version = 1; |  | ||||||
| 
 |  | ||||||
| PyFunctionObject * | PyFunctionObject * | ||||||
| _PyFunction_FromConstructor(PyFrameConstructor *constr) | _PyFunction_FromConstructor(PyFrameConstructor *constr) | ||||||
| { | { | ||||||
|  | @ -128,10 +126,10 @@ uint32_t _PyFunction_GetVersionForCurrentState(PyFunctionObject *func) | ||||||
|     if (func->vectorcall != _PyFunction_Vectorcall) { |     if (func->vectorcall != _PyFunction_Vectorcall) { | ||||||
|         return 0; |         return 0; | ||||||
|     } |     } | ||||||
|     if (next_func_version == 0) { |     if (_PyRuntime.func_state.next_version == 0) { | ||||||
|         return 0; |         return 0; | ||||||
|     } |     } | ||||||
|     uint32_t v = next_func_version++; |     uint32_t v = _PyRuntime.func_state.next_version++; | ||||||
|     func->func_version = v; |     func->func_version = v; | ||||||
|     return v; |     return v; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -4,6 +4,7 @@ | ||||||
| #include "pycore_call.h" | #include "pycore_call.h" | ||||||
| #include "pycore_code.h"          // CO_FAST_FREE | #include "pycore_code.h"          // CO_FAST_FREE | ||||||
| #include "pycore_compile.h"       // _Py_Mangle() | #include "pycore_compile.h"       // _Py_Mangle() | ||||||
|  | #include "pycore_dict.h"          // _PyDict_KeysSize() | ||||||
| #include "pycore_initconfig.h"    // _PyStatus_OK() | #include "pycore_initconfig.h"    // _PyStatus_OK() | ||||||
| #include "pycore_moduleobject.h"  // _PyModule_GetDef() | #include "pycore_moduleobject.h"  // _PyModule_GetDef() | ||||||
| #include "pycore_object.h"        // _PyType_HasFeature() | #include "pycore_object.h"        // _PyType_HasFeature() | ||||||
|  |  | ||||||
|  | @ -208,6 +208,8 @@ | ||||||
|     <ClInclude Include="..\Include\internal\pycore_condvar.h" /> |     <ClInclude Include="..\Include\internal\pycore_condvar.h" /> | ||||||
|     <ClInclude Include="..\Include\internal\pycore_context.h" /> |     <ClInclude Include="..\Include\internal\pycore_context.h" /> | ||||||
|     <ClInclude Include="..\Include\internal\pycore_descrobject.h" /> |     <ClInclude Include="..\Include\internal\pycore_descrobject.h" /> | ||||||
|  |     <ClInclude Include="..\Include\internal\pycore_dict.h" /> | ||||||
|  |     <ClInclude Include="..\Include\internal\pycore_dict_state.h" /> | ||||||
|     <ClInclude Include="..\Include\internal\pycore_dtoa.h" /> |     <ClInclude Include="..\Include\internal\pycore_dtoa.h" /> | ||||||
|     <ClInclude Include="..\Include\internal\pycore_exceptions.h" /> |     <ClInclude Include="..\Include\internal\pycore_exceptions.h" /> | ||||||
|     <ClInclude Include="..\Include\internal\pycore_fileutils.h" /> |     <ClInclude Include="..\Include\internal\pycore_fileutils.h" /> | ||||||
|  |  | ||||||
|  | @ -531,6 +531,12 @@ | ||||||
|     <ClInclude Include="..\Include\internal\pycore_descrobject.h"> |     <ClInclude Include="..\Include\internal\pycore_descrobject.h"> | ||||||
|       <Filter>Include\internal</Filter> |       <Filter>Include\internal</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\Include\internal\pycore_dict.h"> | ||||||
|  |       <Filter>Include\internal</Filter> | ||||||
|  |     </ClInclude> | ||||||
|  |     <ClInclude Include="..\Include\internal\pycore_dict_state.h"> | ||||||
|  |       <Filter>Include\internal</Filter> | ||||||
|  |     </ClInclude> | ||||||
|     <ClInclude Include="..\Include\internal\pycore_dtoa.h"> |     <ClInclude Include="..\Include\internal\pycore_dtoa.h"> | ||||||
|       <Filter>Include\internal</Filter> |       <Filter>Include\internal</Filter> | ||||||
|     </ClInclude> |     </ClInclude> | ||||||
|  |  | ||||||
|  | @ -458,7 +458,7 @@ interpreter_clear(PyInterpreterState *interp, PyThreadState *tstate) | ||||||
|     Py_CLEAR(interp->interpreter_trampoline); |     Py_CLEAR(interp->interpreter_trampoline); | ||||||
| 
 | 
 | ||||||
|     for (int i=0; i < DICT_MAX_WATCHERS; i++) { |     for (int i=0; i < DICT_MAX_WATCHERS; i++) { | ||||||
|         interp->dict_watchers[i] = NULL; |         interp->dict_state.watchers[i] = NULL; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // XXX Once we have one allocator per interpreter (i.e.
 |     // XXX Once we have one allocator per interpreter (i.e.
 | ||||||
|  |  | ||||||
|  | @ -320,9 +320,6 @@ Objects/unicodeobject.c	-	ucnhash_capi	- | ||||||
| Python/suggestions.c	levenshtein_distance	buffer	- | Python/suggestions.c	levenshtein_distance	buffer	- | ||||||
| 
 | 
 | ||||||
| # other | # other | ||||||
| Objects/dictobject.c	-	_pydict_global_version	- |  | ||||||
| Objects/dictobject.c	-	next_dict_keys_version	- |  | ||||||
| Objects/funcobject.c	-	next_func_version	- |  | ||||||
| Objects/object.c	-	_Py_RefTotal	- | Objects/object.c	-	_Py_RefTotal	- | ||||||
| Python/perf_trampoline.c	-	perf_status	- | Python/perf_trampoline.c	-	perf_status	- | ||||||
| Python/perf_trampoline.c	-	extra_code_index	- | Python/perf_trampoline.c	-	extra_code_index	- | ||||||
|  |  | ||||||
| Can't render this file because it has a wrong number of fields in line 4. | 
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Eric Snow
						Eric Snow