diff --git a/vm/src/builtins/dict.rs b/vm/src/builtins/dict.rs index d716a2fd0..210907064 100644 --- a/vm/src/builtins/dict.rs +++ b/vm/src/builtins/dict.rs @@ -468,16 +468,13 @@ impl PyDictRef { // if we lookup local names (which happens all of the time). if self.class().is(&vm.ctx.types.dict_type) { // We can take the short path here! - match self.inner_getitem_option(key, vm) { - Err(exc) => { - if exc.isinstance(&vm.ctx.exceptions.key_error) { - Ok(None) - } else { - Err(exc) - } + self.inner_getitem_option(key, vm).or_else(|exc| { + if exc.isinstance(&vm.ctx.exceptions.key_error) { + Ok(None) + } else { + Err(exc) } - Ok(x) => Ok(x), - } + }) } else { // Fall back to full get_item with KeyError checking diff --git a/vm/src/builtins/function.rs b/vm/src/builtins/function.rs index 595fe63e0..3c699ea1b 100644 --- a/vm/src/builtins/function.rs +++ b/vm/src/builtins/function.rs @@ -324,8 +324,8 @@ pub struct PyBoundMethod { } impl Callable for PyBoundMethod { - fn call(zelf: &PyRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult { - let args = args.insert(zelf.object.clone()); + fn call(zelf: &PyRef, mut args: FuncArgs, vm: &VirtualMachine) -> PyResult { + args.prepend_arg(zelf.object.clone()); vm.invoke(&zelf.function, args) } } diff --git a/vm/src/builtins/pytype.rs b/vm/src/builtins/pytype.rs index cdbe2aec5..8c72b81d9 100644 --- a/vm/src/builtins/pytype.rs +++ b/vm/src/builtins/pytype.rs @@ -398,7 +398,7 @@ impl PyType { ) } #[pyslot] - fn tp_new(metatype: PyTypeRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult { + fn tp_new(metatype: PyTypeRef, mut args: FuncArgs, vm: &VirtualMachine) -> PyResult { vm_trace!("type.__new__ {:?}", args); let is_type_type = metatype.is(&vm.ctx.types.type_type); @@ -439,8 +439,8 @@ impl PyType { #[allow(clippy::redundant_clone)] // false positive if let Some(ref tp_new) = winner.clone().slots.new { // Pass it to the winner - - return tp_new(vm, args.insert(winner.into_object())); + args.prepend_arg(winner.into_object()); + return tp_new(vm, args); } winner } else { @@ -694,18 +694,20 @@ impl DerefToPyType for &'_ T { fn call_tp_new( typ: PyTypeRef, subtype: PyTypeRef, - args: FuncArgs, + mut args: FuncArgs, vm: &VirtualMachine, ) -> PyResult { for cls in typ.deref().iter_mro() { if let Some(new_meth) = cls.get_attr("__new__") { if !vm.ctx.is_tp_new_wrapper(&new_meth) { let new_meth = vm.call_if_get_descriptor(new_meth, typ.clone().into_object())?; - return vm.invoke(&new_meth, args.insert(typ.clone().into_object())); + args.prepend_arg(typ.clone().into_object()); + return vm.invoke(&new_meth, args); } } if let Some(tp_new) = cls.slots.new.as_ref() { - return tp_new(vm, args.insert(subtype.into_object())); + args.prepend_arg(subtype.into_object()); + return tp_new(vm, args); } } unreachable!("Should be able to find a new slot somewhere in the mro") diff --git a/vm/src/function/mod.rs b/vm/src/function/mod.rs index ab4d35fc7..a505ad477 100644 --- a/vm/src/function/mod.rs +++ b/vm/src/function/mod.rs @@ -108,13 +108,9 @@ impl FuncArgs { FuncArgs { args, kwargs } } - pub fn insert(&self, item: PyObjectRef) -> FuncArgs { - let mut args = FuncArgs { - args: self.args.clone(), - kwargs: self.kwargs.clone(), - }; - args.args.insert(0, item); - args + pub fn prepend_arg(&mut self, item: PyObjectRef) { + self.args.reserve_exact(1); + self.args.insert(0, item) } pub fn shift(&mut self) -> PyObjectRef { diff --git a/vm/src/stdlib/signal.rs b/vm/src/stdlib/signal.rs index f1341abf6..c4f8aafa1 100644 --- a/vm/src/stdlib/signal.rs +++ b/vm/src/stdlib/signal.rs @@ -98,15 +98,22 @@ fn _signal_alarm(time: u32) -> u32 { } #[cfg_attr(feature = "flame-it", flame)] +#[inline(always)] pub fn check_signals(vm: &VirtualMachine) -> PyResult<()> { - let signal_handlers = match vm.signal_handlers { - Some(ref h) => h.borrow(), + let signal_handlers = match &vm.signal_handlers { + Some(h) => h, None => return Ok(()), }; if !ANY_TRIGGERED.swap(false, Ordering::Relaxed) { return Ok(()); } + + trigger_signals(&signal_handlers.borrow(), vm) +} +#[inline(never)] +#[cold] +fn trigger_signals(signal_handlers: &[PyObjectRef; NSIG], vm: &VirtualMachine) -> PyResult<()> { for (signum, trigger) in TRIGGERS.iter().enumerate().skip(1) { let triggerd = trigger.swap(false, Ordering::Relaxed); if triggerd {