@@ -556,11 +556,19 @@ static PyGetSetDef frame_getsetlist[] = {
556556 free_list. Else programs creating lots of cyclic trash involving
557557 frames could provoke free_list into growing without bound.
558558*/
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
559567
568+ #if PyFrame_MAXFREELIST > 0
560569static PyFrameObject * free_list = NULL ;
561570static int numfree = 0 ; /* number of frames currently in free_list */
562- /* max value for numfree */
563- #define PyFrame_MAXFREELIST 200
571+ #endif
564572
565573static void _Py_HOT_FUNCTION
566574frame_dealloc (PyFrameObject * f )
@@ -590,15 +598,19 @@ frame_dealloc(PyFrameObject *f)
590598 Py_CLEAR (f -> f_trace );
591599
592600 co = f -> f_code ;
593- if (co -> co_zombieframe == NULL )
601+ if (co -> co_zombieframe == NULL ) {
594602 co -> co_zombieframe = f ;
603+ }
604+ #if PyFrame_MAXFREELIST > 0
595605 else if (numfree < PyFrame_MAXFREELIST ) {
596606 ++ numfree ;
597607 f -> f_back = free_list ;
598608 free_list = f ;
599609 }
600- else
610+ #endif
611+ else {
601612 PyObject_GC_Del (f );
613+ }
602614
603615 Py_DECREF (co );
604616 Py_TRASHCAN_SAFE_END (f )
@@ -759,98 +771,127 @@ PyTypeObject PyFrame_Type = {
759771
760772_Py_IDENTIFIER (__builtins__ );
761773
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 )
765776{
766- PyFrameObject * back = tstate -> frame ;
767777 PyFrameObject * f ;
768- PyObject * builtins ;
769- Py_ssize_t i ;
770778
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 ;
776785 }
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 )
777792#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 ;
785797 }
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 );
788809 return NULL ;
789810 }
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 ;
797812 }
798- else
799- Py_INCREF (builtins );
813+ _Py_NewReference ((PyObject * )f );
814+ }
815+ #endif
800816
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 ;
801822 }
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 ) {
803835 /* If we share the globals, we share the builtins.
804836 Save a lookup and a call. */
805837 builtins = back -> f_builtins ;
806838 assert (builtins != NULL );
807839 Py_INCREF (builtins );
840+ return builtins ;
808841 }
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 );
814847 }
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+ }
845869
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 ;
853887 }
888+
889+ PyFrameObject * f = frame_alloc (code );
890+ if (f == NULL ) {
891+ Py_DECREF (builtins );
892+ return NULL ;
893+ }
894+
854895 f -> f_stacktop = f -> f_valuestack ;
855896 f -> f_builtins = builtins ;
856897 Py_XINCREF (back );
@@ -1142,13 +1183,15 @@ PyFrame_LocalsToFast(PyFrameObject *f, int clear)
11421183void
11431184_PyFrame_ClearFreeList (void )
11441185{
1186+ #if PyFrame_MAXFREELIST > 0
11451187 while (free_list != NULL ) {
11461188 PyFrameObject * f = free_list ;
11471189 free_list = free_list -> f_back ;
11481190 PyObject_GC_Del (f );
11491191 -- numfree ;
11501192 }
11511193 assert (numfree == 0 );
1194+ #endif
11521195}
11531196
11541197void
@@ -1161,9 +1204,11 @@ _PyFrame_Fini(void)
11611204void
11621205_PyFrame_DebugMallocStats (FILE * out )
11631206{
1207+ #if PyFrame_MAXFREELIST > 0
11641208 _PyDebugAllocatorStats (out ,
11651209 "free PyFrameObject" ,
11661210 numfree , sizeof (PyFrameObject ));
1211+ #endif
11671212}
11681213
11691214
0 commit comments