@@ -100,7 +100,7 @@ insert_executor(PyCodeObject *code, _Py_CODEUNIT *instr, int index, _PyExecutorO
100100}
101101
102102static _PyExecutorObject *
103- make_executor_from_uops (_PyUOpInstruction * buffer , int length , const _PyBloomFilter * dependencies );
103+ make_executor_from_uops (_PyUOpInstruction * buffer , int length , const _PyBloomFilter * dependencies , PyObject * constant_pool );
104104
105105static int
106106uop_optimize (_PyInterpreterFrame * frame , _Py_CODEUNIT * instr ,
@@ -388,6 +388,7 @@ static int
388388executor_traverse (PyObject * o , visitproc visit , void * arg )
389389{
390390 _PyExecutorObject * executor = _PyExecutorObject_CAST (o );
391+ Py_VISIT (executor -> constant_pool );
391392 for (uint32_t i = 0 ; i < executor -> exit_count ; i ++ ) {
392393 Py_VISIT (executor -> exits [i ].executor );
393394 }
@@ -1115,13 +1116,15 @@ prepare_for_execution(_PyUOpInstruction *buffer, int length)
11151116/* Executor side exits */
11161117
11171118static _PyExecutorObject *
1118- allocate_executor (int exit_count , int length )
1119+ allocate_executor (int exit_count , int length , PyObject * constant_pool )
11191120{
11201121 int size = exit_count * sizeof (_PyExitData ) + length * sizeof (_PyUOpInstruction );
11211122 _PyExecutorObject * res = PyObject_GC_NewVar (_PyExecutorObject , & _PyUOpExecutor_Type , size );
11221123 if (res == NULL ) {
11231124 return NULL ;
11241125 }
1126+ // Transfer ownership
1127+ res -> constant_pool = constant_pool ;
11251128 res -> trace = (_PyUOpInstruction * )(res -> exits + exit_count );
11261129 res -> code_size = length ;
11271130 res -> exit_count = exit_count ;
@@ -1196,10 +1199,10 @@ sanity_check(_PyExecutorObject *executor)
11961199 * and not a NOP.
11971200 */
11981201static _PyExecutorObject *
1199- make_executor_from_uops (_PyUOpInstruction * buffer , int length , const _PyBloomFilter * dependencies )
1202+ make_executor_from_uops (_PyUOpInstruction * buffer , int length , const _PyBloomFilter * dependencies , PyObject * constant_pool )
12001203{
12011204 int exit_count = count_exits (buffer , length );
1202- _PyExecutorObject * executor = allocate_executor (exit_count , length );
1205+ _PyExecutorObject * executor = allocate_executor (exit_count , length , constant_pool );
12031206 if (executor == NULL ) {
12041207 return NULL ;
12051208 }
@@ -1293,6 +1296,7 @@ uop_optimize(
12931296 _PyBloomFilter dependencies ;
12941297 _Py_BloomFilter_Init (& dependencies );
12951298 PyInterpreterState * interp = _PyInterpreterState_GET ();
1299+ PyObject * constant_pool = NULL ;
12961300 if (interp -> jit_uop_buffer == NULL ) {
12971301 interp -> jit_uop_buffer = (_PyUOpInstruction * )_PyObject_VirtualAlloc (UOP_BUFFER_SIZE );
12981302 if (interp -> jit_uop_buffer == NULL ) {
@@ -1316,7 +1320,7 @@ uop_optimize(
13161320 if (!is_noopt ) {
13171321 length = _Py_uop_analyze_and_optimize (frame , buffer ,
13181322 length ,
1319- curr_stackentries , & dependencies );
1323+ curr_stackentries , & dependencies , & constant_pool );
13201324 if (length <= 0 ) {
13211325 return length ;
13221326 }
@@ -1339,7 +1343,7 @@ uop_optimize(
13391343 OPT_HIST (effective_trace_length (buffer , length ), optimized_trace_length_hist );
13401344 length = prepare_for_execution (buffer , length );
13411345 assert (length <= UOP_MAX_TRACE_LENGTH );
1342- _PyExecutorObject * executor = make_executor_from_uops (buffer , length , & dependencies );
1346+ _PyExecutorObject * executor = make_executor_from_uops (buffer , length , & dependencies , constant_pool );
13431347 if (executor == NULL ) {
13441348 return -1 ;
13451349 }
@@ -1512,7 +1516,7 @@ _PyExecutor_GetColdExecutor(void)
15121516 if (interp -> cold_executor != NULL ) {
15131517 return interp -> cold_executor ;
15141518 }
1515- _PyExecutorObject * cold = allocate_executor (0 , 1 );
1519+ _PyExecutorObject * cold = allocate_executor (0 , 1 , NULL );
15161520 if (cold == NULL ) {
15171521 Py_FatalError ("Cannot allocate core JIT code" );
15181522 }
@@ -1575,6 +1579,8 @@ executor_clear(PyObject *op)
15751579 unlink_executor (executor );
15761580 executor -> vm_data .valid = 0 ;
15771581
1582+ Py_CLEAR (executor -> constant_pool );
1583+
15781584 /* It is possible for an executor to form a reference
15791585 * cycle with itself, so decref'ing a side exit could
15801586 * free the executor unless we hold a strong reference to it
0 commit comments