From e9d2956378e012fcfab7e51079b4a52314a709e5 Mon Sep 17 00:00:00 2001 From: Chris Russell <8494645+chescock@users.noreply.github.com> Date: Thu, 13 Mar 2025 22:38:43 -0400 Subject: [PATCH 1/3] Use new `run_without_applying_deferred` method in `SingleThreadedExecutor`. --- crates/bevy_ecs/src/schedule/executor/mod.rs | 10 +++++ .../src/schedule/executor/single_threaded.rs | 37 +++++-------------- 2 files changed, 20 insertions(+), 27 deletions(-) diff --git a/crates/bevy_ecs/src/schedule/executor/mod.rs b/crates/bevy_ecs/src/schedule/executor/mod.rs index e384680cf4e7a..57df4e5f519d4 100644 --- a/crates/bevy_ecs/src/schedule/executor/mod.rs +++ b/crates/bevy_ecs/src/schedule/executor/mod.rs @@ -303,6 +303,16 @@ mod __rust_begin_short_backtrace { result } + #[inline(never)] + pub(super) fn run_without_applying_deferred( + system: &mut ScheduleSystem, + world: &mut World, + ) -> Result { + let result = system.run_without_applying_deferred((), world); + black_box(()); + result + } + #[inline(never)] pub(super) fn readonly_run( system: &mut dyn ReadOnlySystem, diff --git a/crates/bevy_ecs/src/schedule/executor/single_threaded.rs b/crates/bevy_ecs/src/schedule/executor/single_threaded.rs index b42f47726d50c..82e9e354a80c3 100644 --- a/crates/bevy_ecs/src/schedule/executor/single_threaded.rs +++ b/crates/bevy_ecs/src/schedule/executor/single_threaded.rs @@ -128,33 +128,16 @@ impl SystemExecutor for SingleThreadedExecutor { } let f = AssertUnwindSafe(|| { - if system.is_exclusive() { - if let Err(err) = __rust_begin_short_backtrace::run(system, world) { - error_handler( - err, - ErrorContext::System { - name: system.name(), - last_run: system.get_last_run(), - }, - ); - } - } else { - // Use run_unsafe to avoid immediately applying deferred buffers - let world = world.as_unsafe_world_cell(); - system.update_archetype_component_access(world); - // SAFETY: We have exclusive, single-threaded access to the world and - // update_archetype_component_access is being called immediately before this. - unsafe { - if let Err(err) = __rust_begin_short_backtrace::run_unsafe(system, world) { - error_handler( - err, - ErrorContext::System { - name: system.name(), - last_run: system.get_last_run(), - }, - ); - } - }; + if let Err(err) = + __rust_begin_short_backtrace::run_without_applying_deferred(system, world) + { + error_handler( + err, + ErrorContext::System { + name: system.name(), + last_run: system.get_last_run(), + }, + ); } }); From defb2256c80d14a18ccb2716e844322dcbdca30e Mon Sep 17 00:00:00 2001 From: Chris Russell <8494645+chescock@users.noreply.github.com> Date: Wed, 2 Apr 2025 11:47:24 -0400 Subject: [PATCH 2/3] `run_unsafe` and `readonly_run_unsafe` are only used when `std` is enabled. --- crates/bevy_ecs/src/schedule/executor/mod.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/crates/bevy_ecs/src/schedule/executor/mod.rs b/crates/bevy_ecs/src/schedule/executor/mod.rs index 57df4e5f519d4..2db42c6fbe69c 100644 --- a/crates/bevy_ecs/src/schedule/executor/mod.rs +++ b/crates/bevy_ecs/src/schedule/executor/mod.rs @@ -267,14 +267,18 @@ impl IntoSystemSet<()> for ApplyDeferred { mod __rust_begin_short_backtrace { use core::hint::black_box; + #[cfg(feature = "std")] + use crate::world::unsafe_world_cell::UnsafeWorldCell; use crate::{ error::Result, system::{ReadOnlySystem, ScheduleSystem}, - world::{unsafe_world_cell::UnsafeWorldCell, World}, + world::World, }; /// # Safety /// See `System::run_unsafe`. + // This is only used by `MultiThreadedExecutor`, and would be dead code without `std`. + #[cfg(feature = "std")] #[inline(never)] pub(super) unsafe fn run_unsafe(system: &mut ScheduleSystem, world: UnsafeWorldCell) -> Result { let result = system.run_unsafe((), world); @@ -284,10 +288,8 @@ mod __rust_begin_short_backtrace { /// # Safety /// See `ReadOnlySystem::run_unsafe`. - #[cfg_attr( - not(feature = "std"), - expect(dead_code, reason = "currently only used with the std feature") - )] + // This is only used by `MultiThreadedExecutor`, and would be dead code without `std`. + #[cfg(feature = "std")] #[inline(never)] pub(super) unsafe fn readonly_run_unsafe( system: &mut dyn ReadOnlySystem, From 6058b7bb1e91a8fd28d290a57a2a067e9d9ffa11 Mon Sep 17 00:00:00 2001 From: Chris Russell <8494645+chescock@users.noreply.github.com> Date: Wed, 2 Apr 2025 14:40:37 -0400 Subject: [PATCH 3/3] Add explanation for `black_box` calls. --- crates/bevy_ecs/src/schedule/executor/mod.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crates/bevy_ecs/src/schedule/executor/mod.rs b/crates/bevy_ecs/src/schedule/executor/mod.rs index 2db42c6fbe69c..3b0f83de4e86e 100644 --- a/crates/bevy_ecs/src/schedule/executor/mod.rs +++ b/crates/bevy_ecs/src/schedule/executor/mod.rs @@ -282,6 +282,7 @@ mod __rust_begin_short_backtrace { #[inline(never)] pub(super) unsafe fn run_unsafe(system: &mut ScheduleSystem, world: UnsafeWorldCell) -> Result { let result = system.run_unsafe((), world); + // Call `black_box` to prevent this frame from being tail-call optimized away black_box(()); result } @@ -295,12 +296,14 @@ mod __rust_begin_short_backtrace { system: &mut dyn ReadOnlySystem, world: UnsafeWorldCell, ) -> O { + // Call `black_box` to prevent this frame from being tail-call optimized away black_box(system.run_unsafe((), world)) } #[inline(never)] pub(super) fn run(system: &mut ScheduleSystem, world: &mut World) -> Result { let result = system.run((), world); + // Call `black_box` to prevent this frame from being tail-call optimized away black_box(()); result } @@ -311,6 +314,7 @@ mod __rust_begin_short_backtrace { world: &mut World, ) -> Result { let result = system.run_without_applying_deferred((), world); + // Call `black_box` to prevent this frame from being tail-call optimized away black_box(()); result } @@ -320,6 +324,7 @@ mod __rust_begin_short_backtrace { system: &mut dyn ReadOnlySystem, world: &mut World, ) -> O { + // Call `black_box` to prevent this frame from being tail-call optimized away black_box(system.run((), world)) } }