@@ -9,7 +9,7 @@ use super::{
99use crate :: common:: lock:: OnceCell ;
1010use crate :: common:: lock:: PyMutex ;
1111use crate :: function:: ArgMapping ;
12- use crate :: object:: { Traverse , TraverseFn } ;
12+ use crate :: object:: { PyAtomicRef , Traverse , TraverseFn } ;
1313use crate :: {
1414 AsObject , Context , Py , PyObject , PyObjectRef , PyPayload , PyRef , PyResult , VirtualMachine ,
1515 bytecode,
@@ -61,7 +61,7 @@ fn format_missing_args(
6161#[ pyclass( module = false , name = "function" , traverse = "manual" ) ]
6262#[ derive( Debug ) ]
6363pub struct PyFunction {
64- code : PyMutex < PyRef < PyCode > > ,
64+ code : PyAtomicRef < PyCode > ,
6565 globals : PyDictRef ,
6666 builtins : PyObjectRef ,
6767 closure : Option < PyRef < PyTuple < PyCellRef > > > ,
@@ -192,7 +192,7 @@ impl PyFunction {
192192
193193 let qualname = vm. ctx . new_str ( code. qualname . as_str ( ) ) ;
194194 let func = Self {
195- code : PyMutex :: new ( code. clone ( ) ) ,
195+ code : PyAtomicRef :: from ( code. clone ( ) ) ,
196196 globals,
197197 builtins,
198198 closure : None ,
@@ -217,7 +217,7 @@ impl PyFunction {
217217 func_args : FuncArgs ,
218218 vm : & VirtualMachine ,
219219 ) -> PyResult < ( ) > {
220- let code = & * self . code . lock ( ) ;
220+ let code: & Py < PyCode > = & self . code ;
221221 let nargs = func_args. args . len ( ) ;
222222 let n_expected_args = code. arg_count as usize ;
223223 let total_args = code. arg_count as usize + code. kwonlyarg_count as usize ;
@@ -539,13 +539,12 @@ impl Py<PyFunction> {
539539 Err ( err) => info ! (
540540 "jit: function `{}` is falling back to being interpreted because of the \
541541 error: {}",
542- self . code. lock( ) . obj_name,
543- err
542+ self . code. obj_name, err
544543 ) ,
545544 }
546545 }
547546
548- let code = self . code . lock ( ) . clone ( ) ;
547+ let code: PyRef < PyCode > = ( * self . code ) . to_owned ( ) ;
549548
550549 let locals = if code. flags . contains ( bytecode:: CodeFlags :: NEWLOCALS ) {
551550 None
@@ -608,7 +607,7 @@ impl Py<PyFunction> {
608607 /// Returns true if: no VARARGS, no VARKEYWORDS, no kwonly args, not generator/coroutine,
609608 /// and effective_nargs matches co_argcount.
610609 pub ( crate ) fn can_specialize_call ( & self , effective_nargs : u32 ) -> bool {
611- let code = self . code . lock ( ) ;
610+ let code: & Py < PyCode > = & self . code ;
612611 let flags = code. flags ;
613612 flags. contains ( bytecode:: CodeFlags :: NEWLOCALS )
614613 && !flags. intersects (
@@ -626,7 +625,7 @@ impl Py<PyFunction> {
626625 /// Only valid when: no VARARGS, no VARKEYWORDS, no kwonlyargs, not generator/coroutine,
627626 /// and nargs == co_argcount.
628627 pub fn invoke_exact_args ( & self , args : & [ PyObjectRef ] , vm : & VirtualMachine ) -> PyResult {
629- let code = self . code . lock ( ) . clone ( ) ;
628+ let code: PyRef < PyCode > = ( * self . code ) . to_owned ( ) ;
630629
631630 let frame = Frame :: new (
632631 code. clone ( ) ,
@@ -673,12 +672,12 @@ impl PyPayload for PyFunction {
673672impl PyFunction {
674673 #[ pygetset]
675674 fn __code__ ( & self ) -> PyRef < PyCode > {
676- self . code . lock ( ) . clone ( )
675+ ( * self . code ) . to_owned ( )
677676 }
678677
679678 #[ pygetset( setter) ]
680- fn set___code__ ( & self , code : PyRef < PyCode > ) {
681- * self . code . lock ( ) = code;
679+ fn set___code__ ( & self , code : PyRef < PyCode > , vm : & VirtualMachine ) {
680+ self . code . swap_to_temporary_refs ( code, vm ) ;
682681 self . func_version . store ( 0 , Relaxed ) ;
683682 }
684683
@@ -920,7 +919,7 @@ impl PyFunction {
920919 }
921920 let arg_types = jit:: get_jit_arg_types ( & zelf, vm) ?;
922921 let ret_type = jit:: jit_ret_type ( & zelf, vm) ?;
923- let code = zelf. code . lock ( ) ;
922+ let code: & Py < PyCode > = & zelf. code ;
924923 let compiled = rustpython_jit:: compile ( & code. code , & arg_types, ret_type)
925924 . map_err ( |err| jit:: new_jit_error ( err. to_string ( ) , vm) ) ?;
926925 let _ = zelf. jitted_code . set ( compiled) ;
0 commit comments