@@ -11005,22 +11005,15 @@ slotptr(PyTypeObject *type, int ioffset)
11005
11005
return (void * * )ptr ;
11006
11006
}
11007
11007
11008
- /* Return a slot pointer for a given name, but ONLY if the attribute has
11009
- exactly one slot function. The name must be an interned string. */
11010
- static void * *
11011
- resolve_slotdups (PyTypeObject * type , PyObject * name )
11008
+ static int
11009
+ fill_type_slots_cache_from_slotdefs_cache (PyInterpreterState * interp ,
11010
+ PyObject * name )
11012
11011
{
11013
- PyInterpreterState * interp = _PyInterpreterState_GET ();
11014
-
11015
- /* XXX Maybe this could be optimized more -- but is it worth it? */
11016
- void * * res , * * ptr ;
11017
- res = NULL ;
11012
+ #define ptrs _Py_INTERP_CACHED_OBJECT(interp, type_slots_ptrs)
11018
11013
11014
+ int rc = 0 ;
11019
11015
PyObject * cache = Py_XNewRef (interp -> cached_objects .slotdefs_cache );
11020
11016
if (cache ) {
11021
- int rc = 0 ;
11022
- // Py_BEGIN_CRITICAL_SECTION(cache);
11023
-
11024
11017
PyObject * bytes = NULL ;
11025
11018
rc = PyDict_GetItemRef (cache , name , & bytes );
11026
11019
if (rc > 0 ) {
@@ -11033,53 +11026,61 @@ resolve_slotdups(PyTypeObject *type, PyObject *name)
11033
11026
assert (n >= 0 );
11034
11027
assert (n < MAX_EQUIV );
11035
11028
11036
- uint8_t i ;
11037
- for (i = 0 ; i < n ; i ++ ) {
11029
+ pytype_slotdef * * pp = ptrs ;
11030
+ for (uint8_t i = 0 ; i < n ; i ++ ) {
11038
11031
uint8_t idx = data [i + 1 ];
11039
11032
assert (idx < Py_ARRAY_LENGTH (slotdefs ));
11040
11033
11041
- pytype_slotdef * x = & slotdefs [idx ];
11042
- ptr = slotptr (type , x -> offset );
11043
- if (ptr == NULL || * ptr == NULL ) {
11044
- continue ;
11045
- }
11046
- if (res != NULL ) {
11047
- res = NULL ;
11048
- break ;
11049
- }
11050
- res = ptr ;
11034
+ * pp ++ = & slotdefs [idx ];
11051
11035
}
11036
+ * pp = NULL ;
11037
+
11052
11038
Py_DECREF (bytes );
11053
11039
} else if (rc < 0 ) {
11054
11040
PyErr_Clear ();
11055
11041
}
11056
11042
11057
11043
Py_DECREF (cache );
11058
- // Py_END_CRITICAL_SECTION();
11059
- if (rc > 0 ) {
11060
- return res ;
11061
- }
11062
11044
}
11063
11045
11046
+ return rc ;
11047
+
11048
+ #undef ptrs
11049
+ }
11050
+
11051
+ /* Return a slot pointer for a given name, but ONLY if the attribute has
11052
+ exactly one slot function. The name must be an interned string. */
11053
+ static void * *
11054
+ resolve_slotdups (PyTypeObject * type , PyObject * name )
11055
+ {
11056
+ /* XXX Maybe this could be optimized more -- but is it worth it? */
11057
+
11064
11058
/* pname and ptrs act as a little cache */
11059
+ PyInterpreterState * interp = _PyInterpreterState_GET ();
11065
11060
#define pname _Py_INTERP_CACHED_OBJECT(interp, type_slots_pname)
11066
11061
#define ptrs _Py_INTERP_CACHED_OBJECT(interp, type_slots_ptrs)
11067
11062
pytype_slotdef * p , * * pp ;
11063
+ void * * res , * * ptr ;
11068
11064
11069
11065
if (pname != name ) {
11070
11066
/* Collect all slotdefs that match name into ptrs. */
11071
11067
pname = name ;
11072
- pp = ptrs ;
11073
- for (p = slotdefs ; p -> name_strobj ; p ++ ) {
11074
- if (p -> name_strobj == name )
11075
- * pp ++ = p ;
11068
+
11069
+ int rc = fill_type_slots_cache_from_slotdefs_cache (interp , name );
11070
+ if (rc <= 0 ) {
11071
+ pp = ptrs ;
11072
+ for (p = slotdefs ; p -> name_strobj ; p ++ ) {
11073
+ if (p -> name_strobj == name )
11074
+ * pp ++ = p ;
11075
+ }
11076
+ * pp = NULL ;
11076
11077
}
11077
- * pp = NULL ;
11078
11078
}
11079
11079
11080
11080
/* Look in all slots of the type matching the name. If exactly one of these
11081
11081
has a filled-in slot, return a pointer to that slot.
11082
11082
Otherwise, return NULL. */
11083
+ res = NULL ;
11083
11084
for (pp = ptrs ; * pp ; pp ++ ) {
11084
11085
ptr = slotptr (type , (* pp )-> offset );
11085
11086
if (ptr == NULL || * ptr == NULL )
0 commit comments