88#include "cinderx/StaticPython/generic_type.h"
99#include "cinderx/StaticPython/typed_method_def.h"
1010#include "cinderx/UpstreamBorrow/borrowed.h"
11+ #include "cinderx/module_c_state.h"
1112
1213#if PY_VERSION_HEX < 0x030C0000
1314#include "cinder/exports.h"
1415#endif
1516
16- static PyObject * classloader_cache ;
17- static PyObject * classloader_cache_module_to_keys ;
18-
1917Py_ssize_t _PyClassLoader_PrimitiveTypeToSize (int primitive_type ) {
2018 switch (primitive_type ) {
2119 case TYPED_INT8 :
@@ -375,11 +373,13 @@ _PyClassLoader_ResolveType(PyObject* descr, int* optional, int* exact) {
375373 last = PyTuple_GET_ITEM (descr , items - 1 );
376374 }
377375
378- if (classloader_cache != NULL ) {
379- PyObject * cache = PyDict_GetItem (classloader_cache , descr );
380- if (cache != NULL ) {
381- Py_INCREF (cache );
382- return (PyTypeObject * )cache ;
376+ // Fast path that hits the cache.
377+ PyObject * cl_cache = Ci_GetClassLoaderCache ();
378+ if (cl_cache != NULL ) {
379+ PyObject * cached = PyDict_GetItem (cl_cache , descr );
380+ if (cached != NULL ) {
381+ Py_INCREF (cached );
382+ return (PyTypeObject * )cached ;
383383 }
384384 }
385385
@@ -389,39 +389,37 @@ _PyClassLoader_ResolveType(PyObject* descr, int* optional, int* exact) {
389389 return NULL ;
390390 }
391391
392- if (classloader_cache == NULL ) {
393- classloader_cache = PyDict_New ();
394- if (classloader_cache == NULL ) {
395- Py_DECREF (res );
396- return NULL ;
397- }
392+ // Ensure type resolution cache is set up.
393+ cl_cache = _PyClassLoader_GetCache ();
394+ if (cl_cache == NULL ) {
395+ Py_DECREF (res );
396+ return NULL ;
398397 }
399398
400- if (classloader_cache_module_to_keys == NULL ) {
401- classloader_cache_module_to_keys = PyDict_New ();
402- if (classloader_cache_module_to_keys == NULL ) {
399+ PyObject * mod_to_keys = Ci_GetClassLoaderCacheModuleToKeys ();
400+ if (mod_to_keys == NULL ) {
401+ mod_to_keys = PyDict_New ();
402+ if (mod_to_keys == NULL ) {
403403 Py_DECREF (res );
404404 return NULL ;
405405 }
406+ Ci_SetClassLoaderCacheModuleToKeys ((PyDictObject * )mod_to_keys );
407+ Py_DECREF (mod_to_keys );
406408 }
407409
408- if (PyDict_SetItem (classloader_cache , descr , res )) {
410+ if (PyDict_SetItem (cl_cache , descr , res )) {
409411 Py_DECREF (res );
410412 return NULL ;
411413 }
412414 PyObject * module_key = PyTuple_GET_ITEM (descr , 0 );
413- PyObject * existing_modules_to_keys =
414- PyDict_GetItem (classloader_cache_module_to_keys , module_key );
415+ PyObject * existing_modules_to_keys = PyDict_GetItem (mod_to_keys , module_key );
415416 if (existing_modules_to_keys == NULL ) {
416417 existing_modules_to_keys = PyList_New (0 );
417418 if (existing_modules_to_keys == NULL ) {
418419 Py_DECREF (res );
419420 return NULL ;
420421 }
421- if (PyDict_SetItem (
422- classloader_cache_module_to_keys ,
423- module_key ,
424- existing_modules_to_keys ) < 0 ) {
422+ if (PyDict_SetItem (mod_to_keys , module_key , existing_modules_to_keys ) < 0 ) {
425423 Py_DECREF (res );
426424 return NULL ;
427425 }
@@ -441,34 +439,40 @@ int _PyClassLoader_CheckModuleChange(PyDictObject* dict, PyObject* key) {
441439 if (((PyObject * )dict ) != modules_dict ) {
442440 return 0 ;
443441 }
444- if (classloader_cache_module_to_keys == NULL ) {
442+ PyObject * mod_to_keys = Ci_GetClassLoaderCacheModuleToKeys ();
443+ if (mod_to_keys == NULL ) {
445444 return 0 ;
446445 }
447- PyObject * keys_to_invalidate =
448- PyDict_GetItem (classloader_cache_module_to_keys , key );
446+ PyObject * keys_to_invalidate = PyDict_GetItem (mod_to_keys , key );
449447 if (keys_to_invalidate == NULL ) {
450448 return 0 ;
451449 }
450+ PyObject * cl_cache = Ci_GetClassLoaderCache ();
452451 for (Py_ssize_t i = 0 ; i < PyList_GET_SIZE (keys_to_invalidate ); i ++ ) {
453452 PyObject * key_to_invalidate = PyList_GET_ITEM (keys_to_invalidate , i );
454- if (PyDict_DelItem (classloader_cache , key_to_invalidate ) < 0 ) {
453+ if (PyDict_DelItem (cl_cache , key_to_invalidate ) < 0 ) {
455454 return 0 ;
456455 }
457456 }
458- PyDict_DelItem (classloader_cache_module_to_keys , key );
457+ PyDict_DelItem (mod_to_keys , key );
459458 return 0 ;
460459}
461460
462461void _PyClassLoader_ClearCache () {
463- Py_CLEAR ( classloader_cache );
464- Py_CLEAR ( classloader_cache_module_to_keys );
462+ Ci_ClearClassLoaderCache ( );
463+ Ci_ClearClassLoaderCacheModuleToKeys ( );
465464}
466465
467466PyObject * _PyClassLoader_GetCache () {
468- if (classloader_cache == NULL ) {
469- classloader_cache = PyDict_New ();
467+ PyObject * cl_cache = Ci_GetClassLoaderCache ();
468+ if (cl_cache == NULL ) {
469+ cl_cache = PyDict_New ();
470+ if (cl_cache != NULL ) {
471+ Ci_SetClassLoaderCache ((PyDictObject * )cl_cache );
472+ Py_DECREF (cl_cache );
473+ }
470474 }
471- return classloader_cache ;
475+ return cl_cache ;
472476}
473477
474478/* Resolve a tuple type descr to a `prim_type` integer (`TYPED_*`); return -1
0 commit comments