mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 21:51:50 +00:00 
			
		
		
		
	gh-123923: Defer refcounting for f_executable in _PyInterpreterFrame (#123924)
				
					
				
			Use a `_PyStackRef` and defer the reference to `f_executable` when possible. This avoids some reference count contention in the common case of executing the same code object from multiple threads concurrently in the free-threaded build.
This commit is contained in:
		
							parent
							
								
									4ed7d1d6ac
								
							
						
					
					
						commit
						b2afe2aae4
					
				
					 18 changed files with 177 additions and 99 deletions
				
			
		|  | @ -14,7 +14,10 @@ _PyFrame_Traverse(_PyInterpreterFrame *frame, visitproc visit, void *arg) | |||
|     Py_VISIT(frame->frame_obj); | ||||
|     Py_VISIT(frame->f_locals); | ||||
|     Py_VISIT(frame->f_funcobj); | ||||
|     Py_VISIT(_PyFrame_GetCode(frame)); | ||||
|     int err = _PyGC_VisitStackRef(&frame->f_executable, visit, arg); | ||||
|     if (err) { | ||||
|         return err; | ||||
|     } | ||||
|     return _PyGC_VisitFrameStack(frame, visit, arg); | ||||
| } | ||||
| 
 | ||||
|  | @ -53,10 +56,10 @@ take_ownership(PyFrameObject *f, _PyInterpreterFrame *frame) | |||
|     assert(frame->owner != FRAME_OWNED_BY_FRAME_OBJECT); | ||||
|     assert(frame->owner != FRAME_CLEARED); | ||||
|     Py_ssize_t size = ((char*)frame->stackpointer) - (char *)frame; | ||||
|     Py_INCREF(_PyFrame_GetCode(frame)); | ||||
|     memcpy((_PyInterpreterFrame *)f->_f_frame_data, frame, size); | ||||
|     frame = (_PyInterpreterFrame *)f->_f_frame_data; | ||||
|     frame->stackpointer = (_PyStackRef *)(((char *)frame) + size); | ||||
|     frame->f_executable = PyStackRef_DUP(frame->f_executable); | ||||
|     f->f_frame = frame; | ||||
|     frame->owner = FRAME_OWNED_BY_FRAME_OBJECT; | ||||
|     if (_PyFrame_IsIncomplete(frame)) { | ||||
|  | @ -131,9 +134,7 @@ _PyFrame_ClearExceptCode(_PyInterpreterFrame *frame) | |||
| PyObject * | ||||
| PyUnstable_InterpreterFrame_GetCode(struct _PyInterpreterFrame *frame) | ||||
| { | ||||
|     PyObject *code = frame->f_executable; | ||||
|     Py_INCREF(code); | ||||
|     return code; | ||||
|     return PyStackRef_AsPyObjectNew(frame->f_executable); | ||||
| } | ||||
| 
 | ||||
| int | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Sam Gross
						Sam Gross