@@ -44,6 +44,7 @@ static const char copyright[] =
4444#include "pycore_long.h" // _PyLong_GetZero()
4545#include "pycore_list.h" // _PyList_AppendTakeRef()
4646#include "pycore_moduleobject.h" // _PyModule_GetState()
47+ #include "pycore_object.h" // _Py_NewReference()
4748#include "pycore_tuple.h" // _PyTuple_FromPairSteal
4849#include "pycore_unicodeobject.h" // _PyUnicode_Copy
4950#include "pycore_unicodectype.h" // _PyUnicode_IsXidStart()
@@ -875,6 +876,12 @@ static int
875876pattern_clear (PyObject * op )
876877{
877878 PatternObject * self = _PatternObject_CAST (op );
879+ PyObject * cached = _Py_atomic_exchange_ptr (& self -> cached_match , NULL );
880+ if (cached != NULL ) {
881+ PyTypeObject * tp = Py_TYPE (cached );
882+ PyObject_GC_Del (cached );
883+ Py_DECREF (tp );
884+ }
878885 Py_CLEAR (self -> groupindex );
879886 Py_CLEAR (self -> indexgroup );
880887 Py_CLEAR (self -> pattern );
@@ -1788,6 +1795,7 @@ _sre_compile_impl(PyObject *module, PyObject *pattern, int flags,
17881795 if (!self )
17891796 return NULL ;
17901797 self -> weakreflist = NULL ;
1798+ self -> cached_match = NULL ;
17911799 self -> pattern = NULL ;
17921800 self -> groupindex = NULL ;
17931801 self -> indexgroup = NULL ;
@@ -2505,7 +2513,24 @@ match_dealloc(PyObject *self)
25052513{
25062514 PyTypeObject * tp = Py_TYPE (self );
25072515 PyObject_GC_UnTrack (self );
2508- (void )match_clear (self );
2516+ MatchObject * match = _MatchObject_CAST (self );
2517+ PatternObject * pattern = match -> pattern ;
2518+ Py_CLEAR (match -> string );
2519+ Py_CLEAR (match -> regs );
2520+ if (pattern != NULL ) {
2521+ match -> pattern = NULL ;
2522+ /* Cache the dead object (it keeps only its type reference) in the
2523+ pattern for the next match. The pattern reference is given up
2524+ either way; if it was the last one, pattern_clear() frees the
2525+ object just cached. */
2526+ PyObject * expected = NULL ;
2527+ if (_Py_atomic_compare_exchange_ptr (& pattern -> cached_match ,
2528+ & expected , self )) {
2529+ Py_DECREF (pattern );
2530+ return ;
2531+ }
2532+ Py_DECREF (pattern );
2533+ }
25092534 tp -> tp_free (self );
25102535 Py_DECREF (tp );
25112536}
@@ -2950,12 +2975,20 @@ pattern_new_match(_sremodulestate* module_state,
29502975 if (status > 0 ) {
29512976
29522977 /* create match object (with room for extra group marks) */
2953- /* coverity[ampersand_in_size] */
2954- match = PyObject_GC_NewVar (MatchObject ,
2955- module_state -> Match_Type ,
2956- 2 * (pattern -> groups + 1 ));
2957- if (!match )
2958- return NULL ;
2978+ match = (MatchObject * )_Py_atomic_exchange_ptr (& pattern -> cached_match ,
2979+ NULL );
2980+ if (match != NULL ) {
2981+ assert (Py_SIZE (match ) == 2 * (pattern -> groups + 1 ));
2982+ _Py_NewReference ((PyObject * )match );
2983+ }
2984+ else {
2985+ /* coverity[ampersand_in_size] */
2986+ match = PyObject_GC_NewVar (MatchObject ,
2987+ module_state -> Match_Type ,
2988+ 2 * (pattern -> groups + 1 ));
2989+ if (!match )
2990+ return NULL ;
2991+ }
29592992
29602993 Py_INCREF (pattern );
29612994 match -> pattern = pattern ;
0 commit comments