diff --git a/rivet/runtime/windows/src/browser/chromium.rs b/rivet/runtime/windows/src/browser/chromium.rs index 59ffa51..f5131c5 100644 --- a/rivet/runtime/windows/src/browser/chromium.rs +++ b/rivet/runtime/windows/src/browser/chromium.rs @@ -104,6 +104,10 @@ impl TabMoves for Chromium { fn read_word(address: usize) -> Option { use windows_sys::Win32::System::Diagnostics::Debug::ReadProcessMemory; use windows_sys::Win32::System::Threading::GetCurrentProcess; + // A word known readable is read in place, without a system call. + if let Some(value) = crate::chromium::memory::read_word(address) { + return Some(value); + } let mut value = 0usize; let mut done = 0usize; // ReadProcessMemory fails, instead of faulting, on an address that is not mapped. diff --git a/rivet/runtime/windows/src/features/app_window.rs b/rivet/runtime/windows/src/features/app_window.rs index 26b60bd..87dd96e 100644 --- a/rivet/runtime/windows/src/features/app_window.rs +++ b/rivet/runtime/windows/src/features/app_window.rs @@ -402,6 +402,9 @@ pub(crate) unsafe fn flip_new_tab(window: HWND, offsets: &[usize]) -> bool { unsafe fn safe_word(address: usize) -> Option { use windows_sys::Win32::System::Diagnostics::Debug::ReadProcessMemory; use windows_sys::Win32::System::Threading::GetCurrentProcess; + if let Some(value) = crate::chromium::memory::read_word(address) { + return Some(value); + } let mut value = 0usize; let mut done = 0usize; let ok = ReadProcessMemory( diff --git a/rivet/runtime/windows/src/features/tab_strip.rs b/rivet/runtime/windows/src/features/tab_strip.rs index c8e37cd..cd156af 100644 --- a/rivet/runtime/windows/src/features/tab_strip.rs +++ b/rivet/runtime/windows/src/features/tab_strip.rs @@ -147,6 +147,11 @@ const BOUNDS: usize = 0x1C0; /// A word of memory that may not belong to a view, read so that a wrong guess cannot fault. unsafe fn read(address: usize, bytes: usize, out: *mut u8) -> bool { use windows_sys::Win32::System::Diagnostics::Debug::ReadProcessMemory; + // Memory known readable is copied in place, without a system call for every word. + if address > 0x10000 && crate::chromium::memory::readable(address, bytes) { + std::ptr::copy_nonoverlapping(address as *const u8, out, bytes); + return true; + } address > 0x10000 && ReadProcessMemory( windows_sys::Win32::System::Threading::GetCurrentProcess(), diff --git a/rivet/runtime/windows/src/frame.rs b/rivet/runtime/windows/src/frame.rs index 0f6f243..8dc07c3 100644 --- a/rivet/runtime/windows/src/frame.rs +++ b/rivet/runtime/windows/src/frame.rs @@ -3125,12 +3125,14 @@ pub(crate) unsafe fn update_top_bar(window: HWND) { if crate::features::address_bar::busy() { return; } + let mut laps = Laps::start(); let dpi = layout_dpi(window); let top_bar = if framed(window) { crate::features::address_bar::view(window) } else { None }; + laps.mark("view"); APPBARS.with(|appbars| { if let Some(appbar) = appbars.borrow_mut().get_mut(&(window as isize)) { if let Err(error) = appbar.update_address(window as isize, top_bar.as_ref(), dpi) { @@ -3138,6 +3140,10 @@ pub(crate) unsafe fn update_top_bar(window: HWND) { } } }); + laps.mark("paint"); + if laps.total_us() >= SLOW_UPDATE_US && crate::trace::tracing() { + crate::trace::trace(&laps.line().replacen("appbar:", "top bar:", 1)); + } } /// The steps of one surface update and how long each took, in microseconds.