@@ -128,7 +128,7 @@ _PyFunction_FromConstructor(PyFrameConstructor *constr)
128
128
op -> func_annotate = NULL ;
129
129
op -> func_typeparams = NULL ;
130
130
op -> vectorcall = _PyFunction_Vectorcall ;
131
- op -> func_version = 0 ;
131
+ op -> func_version = FUNC_VERSION_UNSET ;
132
132
// NOTE: functions created via FrameConstructor do not use deferred
133
133
// reference counting because they are typically not part of cycles
134
134
// nor accessed by multiple threads.
@@ -207,7 +207,7 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname
207
207
op -> func_annotate = NULL ;
208
208
op -> func_typeparams = NULL ;
209
209
op -> vectorcall = _PyFunction_Vectorcall ;
210
- op -> func_version = 0 ;
210
+ op -> func_version = FUNC_VERSION_UNSET ;
211
211
if ((code_obj -> co_flags & CO_NESTED ) == 0 ) {
212
212
// Use deferred reference counting for top-level functions, but not
213
213
// nested functions because they are more likely to capture variables,
@@ -287,41 +287,67 @@ functions is running.
287
287
288
288
*/
289
289
290
+ static inline struct _func_version_cache_item *
291
+ get_cache_item (PyInterpreterState * interp , uint32_t version )
292
+ {
293
+ return interp -> func_state .func_version_cache +
294
+ (version % FUNC_VERSION_CACHE_SIZE );
295
+ }
296
+
290
297
void
291
298
_PyFunction_SetVersion (PyFunctionObject * func , uint32_t version )
292
299
{
300
+ assert (func -> func_version == FUNC_VERSION_UNSET );
301
+ assert (version >= FUNC_VERSION_FIRST_VALID );
302
+ // This should only be called from MAKE_FUNCTION. No code is specialized
303
+ // based on the version, so we do not need to stop the world to set it.
304
+ func -> func_version = version ;
293
305
#ifndef Py_GIL_DISABLED
294
306
PyInterpreterState * interp = _PyInterpreterState_GET ();
295
- if (func -> func_version != 0 ) {
296
- struct _func_version_cache_item * slot =
297
- interp -> func_state .func_version_cache
298
- + (func -> func_version % FUNC_VERSION_CACHE_SIZE );
299
- if (slot -> func == func ) {
300
- slot -> func = NULL ;
301
- // Leave slot->code alone, there may be use for it.
302
- }
303
- }
307
+ struct _func_version_cache_item * slot = get_cache_item (interp , version );
308
+ slot -> func = func ;
309
+ slot -> code = func -> func_code ;
304
310
#endif
305
- func -> func_version = version ;
311
+ }
312
+
313
+ static void
314
+ func_clear_version (PyInterpreterState * interp , PyFunctionObject * func )
315
+ {
316
+ if (func -> func_version < FUNC_VERSION_FIRST_VALID ) {
317
+ // Version was never set or has already been cleared.
318
+ return ;
319
+ }
306
320
#ifndef Py_GIL_DISABLED
307
- if (version != 0 ) {
308
- struct _func_version_cache_item * slot =
309
- interp -> func_state .func_version_cache
310
- + (version % FUNC_VERSION_CACHE_SIZE );
311
- slot -> func = func ;
312
- slot -> code = func -> func_code ;
321
+ struct _func_version_cache_item * slot =
322
+ get_cache_item (interp , func -> func_version );
323
+ if (slot -> func == func ) {
324
+ slot -> func = NULL ;
325
+ // Leave slot->code alone, there may be use for it.
313
326
}
314
327
#endif
328
+ func -> func_version = FUNC_VERSION_CLEARED ;
329
+ }
330
+
331
+ // Called when any of the critical function attributes are changed
332
+ static void
333
+ _PyFunction_ClearVersion (PyFunctionObject * func )
334
+ {
335
+ if (func -> func_version < FUNC_VERSION_FIRST_VALID ) {
336
+ // Version was never set or has already been cleared.
337
+ return ;
338
+ }
339
+ PyInterpreterState * interp = _PyInterpreterState_GET ();
340
+ _PyEval_StopTheWorld (interp );
341
+ func_clear_version (interp , func );
342
+ _PyEval_StartTheWorld (interp );
315
343
}
316
344
317
345
void
318
346
_PyFunction_ClearCodeByVersion (uint32_t version )
319
347
{
320
348
#ifndef Py_GIL_DISABLED
321
349
PyInterpreterState * interp = _PyInterpreterState_GET ();
322
- struct _func_version_cache_item * slot =
323
- interp -> func_state .func_version_cache
324
- + (version % FUNC_VERSION_CACHE_SIZE );
350
+ struct _func_version_cache_item * slot = get_cache_item (interp , version );
325
351
if (slot -> code ) {
326
352
assert (PyCode_Check (slot -> code ));
327
353
PyCodeObject * code = (PyCodeObject * )slot -> code ;
@@ -340,9 +366,7 @@ _PyFunction_LookupByVersion(uint32_t version, PyObject **p_code)
340
366
return NULL ;
341
367
#else
342
368
PyInterpreterState * interp = _PyInterpreterState_GET ();
343
- struct _func_version_cache_item * slot =
344
- interp -> func_state .func_version_cache
345
- + (version % FUNC_VERSION_CACHE_SIZE );
369
+ struct _func_version_cache_item * slot = get_cache_item (interp , version );
346
370
if (slot -> code ) {
347
371
assert (PyCode_Check (slot -> code ));
348
372
PyCodeObject * code = (PyCodeObject * )slot -> code ;
@@ -431,7 +455,7 @@ PyFunction_SetDefaults(PyObject *op, PyObject *defaults)
431
455
}
432
456
handle_func_event (PyFunction_EVENT_MODIFY_DEFAULTS ,
433
457
(PyFunctionObject * ) op , defaults );
434
- _PyFunction_SetVersion ((PyFunctionObject * )op , 0 );
458
+ _PyFunction_ClearVersion ((PyFunctionObject * )op );
435
459
Py_XSETREF (((PyFunctionObject * )op )-> func_defaults , defaults );
436
460
return 0 ;
437
461
}
440
464
PyFunction_SetVectorcall (PyFunctionObject * func , vectorcallfunc vectorcall )
441
465
{
442
466
assert (func != NULL );
443
- _PyFunction_SetVersion (func , 0 );
467
+ _PyFunction_ClearVersion (func );
444
468
func -> vectorcall = vectorcall ;
445
469
}
446
470
@@ -473,7 +497,7 @@ PyFunction_SetKwDefaults(PyObject *op, PyObject *defaults)
473
497
}
474
498
handle_func_event (PyFunction_EVENT_MODIFY_KWDEFAULTS ,
475
499
(PyFunctionObject * ) op , defaults );
476
- _PyFunction_SetVersion ((PyFunctionObject * )op , 0 );
500
+ _PyFunction_ClearVersion ((PyFunctionObject * )op );
477
501
Py_XSETREF (((PyFunctionObject * )op )-> func_kwdefaults , defaults );
478
502
return 0 ;
479
503
}
@@ -506,7 +530,7 @@ PyFunction_SetClosure(PyObject *op, PyObject *closure)
506
530
Py_TYPE (closure )-> tp_name );
507
531
return -1 ;
508
532
}
509
- _PyFunction_SetVersion ((PyFunctionObject * )op , 0 );
533
+ _PyFunction_ClearVersion ((PyFunctionObject * )op );
510
534
Py_XSETREF (((PyFunctionObject * )op )-> func_closure , closure );
511
535
return 0 ;
512
536
}
@@ -658,7 +682,7 @@ func_set_code(PyObject *self, PyObject *value, void *Py_UNUSED(ignored))
658
682
}
659
683
660
684
handle_func_event (PyFunction_EVENT_MODIFY_CODE , op , value );
661
- _PyFunction_SetVersion (op , 0 );
685
+ _PyFunction_ClearVersion (op );
662
686
Py_XSETREF (op -> func_code , Py_NewRef (value ));
663
687
return 0 ;
664
688
}
@@ -744,7 +768,7 @@ func_set_defaults(PyObject *self, PyObject *value, void *Py_UNUSED(ignored))
744
768
}
745
769
746
770
handle_func_event (PyFunction_EVENT_MODIFY_DEFAULTS , op , value );
747
- _PyFunction_SetVersion (op , 0 );
771
+ _PyFunction_ClearVersion (op );
748
772
Py_XSETREF (op -> func_defaults , Py_XNewRef (value ));
749
773
return 0 ;
750
774
}
@@ -787,7 +811,7 @@ func_set_kwdefaults(PyObject *self, PyObject *value, void *Py_UNUSED(ignored))
787
811
}
788
812
789
813
handle_func_event (PyFunction_EVENT_MODIFY_KWDEFAULTS , op , value );
790
- _PyFunction_SetVersion (op , 0 );
814
+ _PyFunction_ClearVersion (op );
791
815
Py_XSETREF (op -> func_kwdefaults , Py_XNewRef (value ));
792
816
return 0 ;
793
817
}
@@ -1030,7 +1054,7 @@ static int
1030
1054
func_clear (PyObject * self )
1031
1055
{
1032
1056
PyFunctionObject * op = _PyFunction_CAST (self );
1033
- _PyFunction_SetVersion ( op , 0 );
1057
+ func_clear_version ( _PyInterpreterState_GET (), op );
1034
1058
Py_CLEAR (op -> func_globals );
1035
1059
Py_CLEAR (op -> func_builtins );
1036
1060
Py_CLEAR (op -> func_module );
@@ -1068,7 +1092,6 @@ func_dealloc(PyObject *self)
1068
1092
if (op -> func_weakreflist != NULL ) {
1069
1093
PyObject_ClearWeakRefs ((PyObject * ) op );
1070
1094
}
1071
- _PyFunction_SetVersion (op , 0 );
1072
1095
(void )func_clear ((PyObject * )op );
1073
1096
// These aren't cleared by func_clear().
1074
1097
Py_DECREF (op -> func_code );
0 commit comments