@@ -556,11 +556,19 @@ static PyGetSetDef frame_getsetlist[] = {
556
556
free_list. Else programs creating lots of cyclic trash involving
557
557
frames could provoke free_list into growing without bound.
558
558
*/
559
+ /* max value for numfree */
560
+ #define PyFrame_MAXFREELIST 200
561
+
562
+ /* bpo-40521: frame free lists are shared by all interpreters. */
563
+ #ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
564
+ # undef PyFrame_MAXFREELIST
565
+ # define PyFrame_MAXFREELIST 0
566
+ #endif
559
567
568
+ #if PyFrame_MAXFREELIST > 0
560
569
static PyFrameObject * free_list = NULL ;
561
570
static int numfree = 0 ; /* number of frames currently in free_list */
562
- /* max value for numfree */
563
- #define PyFrame_MAXFREELIST 200
571
+ #endif
564
572
565
573
static void _Py_HOT_FUNCTION
566
574
frame_dealloc (PyFrameObject * f )
@@ -590,15 +598,19 @@ frame_dealloc(PyFrameObject *f)
590
598
Py_CLEAR (f -> f_trace );
591
599
592
600
co = f -> f_code ;
593
- if (co -> co_zombieframe == NULL )
601
+ if (co -> co_zombieframe == NULL ) {
594
602
co -> co_zombieframe = f ;
603
+ }
604
+ #if PyFrame_MAXFREELIST > 0
595
605
else if (numfree < PyFrame_MAXFREELIST ) {
596
606
++ numfree ;
597
607
f -> f_back = free_list ;
598
608
free_list = f ;
599
609
}
600
- else
610
+ #endif
611
+ else {
601
612
PyObject_GC_Del (f );
613
+ }
602
614
603
615
Py_DECREF (co );
604
616
Py_TRASHCAN_SAFE_END (f )
@@ -759,98 +771,127 @@ PyTypeObject PyFrame_Type = {
759
771
760
772
_Py_IDENTIFIER (__builtins__ );
761
773
762
- PyFrameObject * _Py_HOT_FUNCTION
763
- _PyFrame_New_NoTrack (PyThreadState * tstate , PyCodeObject * code ,
764
- PyObject * globals , PyObject * locals )
774
+ static inline PyFrameObject *
775
+ frame_alloc (PyCodeObject * code )
765
776
{
766
- PyFrameObject * back = tstate -> frame ;
767
777
PyFrameObject * f ;
768
- PyObject * builtins ;
769
- Py_ssize_t i ;
770
778
771
- #ifdef Py_DEBUG
772
- if (code == NULL || globals == NULL || !PyDict_Check (globals ) ||
773
- (locals != NULL && !PyMapping_Check (locals ))) {
774
- PyErr_BadInternalCall ();
775
- return NULL ;
779
+ f = code -> co_zombieframe ;
780
+ if (f != NULL ) {
781
+ code -> co_zombieframe = NULL ;
782
+ _Py_NewReference ((PyObject * )f );
783
+ assert (f -> f_code == code );
784
+ return f ;
776
785
}
786
+
787
+ Py_ssize_t ncells = PyTuple_GET_SIZE (code -> co_cellvars );
788
+ Py_ssize_t nfrees = PyTuple_GET_SIZE (code -> co_freevars );
789
+ Py_ssize_t extras = code -> co_stacksize + code -> co_nlocals + ncells + nfrees ;
790
+ #if PyFrame_MAXFREELIST > 0
791
+ if (free_list == NULL )
777
792
#endif
778
- if (back == NULL || back -> f_globals != globals ) {
779
- builtins = _PyDict_GetItemIdWithError (globals , & PyId___builtins__ );
780
- if (builtins ) {
781
- if (PyModule_Check (builtins )) {
782
- builtins = PyModule_GetDict (builtins );
783
- assert (builtins != NULL );
784
- }
793
+ {
794
+ f = PyObject_GC_NewVar (PyFrameObject , & PyFrame_Type , extras );
795
+ if (f == NULL ) {
796
+ return NULL ;
785
797
}
786
- if (builtins == NULL ) {
787
- if (PyErr_Occurred ()) {
798
+ }
799
+ #if PyFrame_MAXFREELIST > 0
800
+ else {
801
+ assert (numfree > 0 );
802
+ -- numfree ;
803
+ f = free_list ;
804
+ free_list = free_list -> f_back ;
805
+ if (Py_SIZE (f ) < extras ) {
806
+ PyFrameObject * new_f = PyObject_GC_Resize (PyFrameObject , f , extras );
807
+ if (new_f == NULL ) {
808
+ PyObject_GC_Del (f );
788
809
return NULL ;
789
810
}
790
- /* No builtins! Make up a minimal one
791
- Give them 'None', at least. */
792
- builtins = PyDict_New ();
793
- if (builtins == NULL ||
794
- PyDict_SetItemString (
795
- builtins , "None" , Py_None ) < 0 )
796
- return NULL ;
811
+ f = new_f ;
797
812
}
798
- else
799
- Py_INCREF (builtins );
813
+ _Py_NewReference ((PyObject * )f );
814
+ }
815
+ #endif
800
816
817
+ f -> f_code = code ;
818
+ extras = code -> co_nlocals + ncells + nfrees ;
819
+ f -> f_valuestack = f -> f_localsplus + extras ;
820
+ for (Py_ssize_t i = 0 ; i < extras ; i ++ ) {
821
+ f -> f_localsplus [i ] = NULL ;
801
822
}
802
- else {
823
+ f -> f_locals = NULL ;
824
+ f -> f_trace = NULL ;
825
+ return f ;
826
+ }
827
+
828
+
829
+ static inline PyObject *
830
+ frame_get_builtins (PyFrameObject * back , PyObject * globals )
831
+ {
832
+ PyObject * builtins ;
833
+
834
+ if (back != NULL && back -> f_globals == globals ) {
803
835
/* If we share the globals, we share the builtins.
804
836
Save a lookup and a call. */
805
837
builtins = back -> f_builtins ;
806
838
assert (builtins != NULL );
807
839
Py_INCREF (builtins );
840
+ return builtins ;
808
841
}
809
- if ( code -> co_zombieframe != NULL ) {
810
- f = code -> co_zombieframe ;
811
- code -> co_zombieframe = NULL ;
812
- _Py_NewReference (( PyObject * ) f );
813
- assert (f -> f_code == code );
842
+
843
+ builtins = _PyDict_GetItemIdWithError ( globals , & PyId___builtins__ ) ;
844
+ if ( builtins != NULL && PyModule_Check ( builtins )) {
845
+ builtins = PyModule_GetDict ( builtins );
846
+ assert (builtins != NULL );
814
847
}
815
- else {
816
- Py_ssize_t extras , ncells , nfrees ;
817
- ncells = PyTuple_GET_SIZE (code -> co_cellvars );
818
- nfrees = PyTuple_GET_SIZE (code -> co_freevars );
819
- extras = code -> co_stacksize + code -> co_nlocals + ncells +
820
- nfrees ;
821
- if (free_list == NULL ) {
822
- f = PyObject_GC_NewVar (PyFrameObject , & PyFrame_Type ,
823
- extras );
824
- if (f == NULL ) {
825
- Py_DECREF (builtins );
826
- return NULL ;
827
- }
828
- }
829
- else {
830
- assert (numfree > 0 );
831
- -- numfree ;
832
- f = free_list ;
833
- free_list = free_list -> f_back ;
834
- if (Py_SIZE (f ) < extras ) {
835
- PyFrameObject * new_f = PyObject_GC_Resize (PyFrameObject , f , extras );
836
- if (new_f == NULL ) {
837
- PyObject_GC_Del (f );
838
- Py_DECREF (builtins );
839
- return NULL ;
840
- }
841
- f = new_f ;
842
- }
843
- _Py_NewReference ((PyObject * )f );
844
- }
848
+ if (builtins != NULL ) {
849
+ Py_INCREF (builtins );
850
+ return builtins ;
851
+ }
852
+
853
+ if (PyErr_Occurred ()) {
854
+ return NULL ;
855
+ }
856
+
857
+ /* No builtins! Make up a minimal one.
858
+ Give them 'None', at least. */
859
+ builtins = PyDict_New ();
860
+ if (builtins == NULL ) {
861
+ return NULL ;
862
+ }
863
+ if (PyDict_SetItemString (builtins , "None" , Py_None ) < 0 ) {
864
+ Py_DECREF (builtins );
865
+ return NULL ;
866
+ }
867
+ return builtins ;
868
+ }
845
869
846
- f -> f_code = code ;
847
- extras = code -> co_nlocals + ncells + nfrees ;
848
- f -> f_valuestack = f -> f_localsplus + extras ;
849
- for (i = 0 ; i < extras ; i ++ )
850
- f -> f_localsplus [i ] = NULL ;
851
- f -> f_locals = NULL ;
852
- f -> f_trace = NULL ;
870
+
871
+ PyFrameObject * _Py_HOT_FUNCTION
872
+ _PyFrame_New_NoTrack (PyThreadState * tstate , PyCodeObject * code ,
873
+ PyObject * globals , PyObject * locals )
874
+ {
875
+ #ifdef Py_DEBUG
876
+ if (code == NULL || globals == NULL || !PyDict_Check (globals ) ||
877
+ (locals != NULL && !PyMapping_Check (locals ))) {
878
+ PyErr_BadInternalCall ();
879
+ return NULL ;
880
+ }
881
+ #endif
882
+
883
+ PyFrameObject * back = tstate -> frame ;
884
+ PyObject * builtins = frame_get_builtins (back , globals );
885
+ if (builtins == NULL ) {
886
+ return NULL ;
853
887
}
888
+
889
+ PyFrameObject * f = frame_alloc (code );
890
+ if (f == NULL ) {
891
+ Py_DECREF (builtins );
892
+ return NULL ;
893
+ }
894
+
854
895
f -> f_stacktop = f -> f_valuestack ;
855
896
f -> f_builtins = builtins ;
856
897
Py_XINCREF (back );
@@ -1142,13 +1183,15 @@ PyFrame_LocalsToFast(PyFrameObject *f, int clear)
1142
1183
void
1143
1184
_PyFrame_ClearFreeList (void )
1144
1185
{
1186
+ #if PyFrame_MAXFREELIST > 0
1145
1187
while (free_list != NULL ) {
1146
1188
PyFrameObject * f = free_list ;
1147
1189
free_list = free_list -> f_back ;
1148
1190
PyObject_GC_Del (f );
1149
1191
-- numfree ;
1150
1192
}
1151
1193
assert (numfree == 0 );
1194
+ #endif
1152
1195
}
1153
1196
1154
1197
void
@@ -1161,9 +1204,11 @@ _PyFrame_Fini(void)
1161
1204
void
1162
1205
_PyFrame_DebugMallocStats (FILE * out )
1163
1206
{
1207
+ #if PyFrame_MAXFREELIST > 0
1164
1208
_PyDebugAllocatorStats (out ,
1165
1209
"free PyFrameObject" ,
1166
1210
numfree , sizeof (PyFrameObject ));
1211
+ #endif
1167
1212
}
1168
1213
1169
1214
0 commit comments