refactor: Add utils.rs
This commit is contained in:
parent
5cef362dbd
commit
b4903f2b3d
|
@ -4,20 +4,6 @@ use std::mem::{align_of, ManuallyDrop};
|
|||
use std::ops::{Add, AddAssign};
|
||||
use std::ptr;
|
||||
|
||||
#[cfg(sailfish_nightly)]
|
||||
macro_rules! unlikely {
|
||||
($val:expr) => {
|
||||
std::intrinsics::unlikely($val)
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(not(sailfish_nightly))]
|
||||
macro_rules! unlikely {
|
||||
($val:expr) => {
|
||||
$val
|
||||
};
|
||||
}
|
||||
|
||||
/// Buffer for rendered contents
|
||||
///
|
||||
/// This struct is quite simular to `String`, but some methods are
|
||||
|
@ -41,7 +27,7 @@ impl Buffer {
|
|||
#[cfg_attr(feature = "perf-inline", inline)]
|
||||
pub fn with_capacity(n: usize) -> Buffer {
|
||||
unsafe {
|
||||
if n == 0 {
|
||||
if unlikely!(n == 0) {
|
||||
Self::new()
|
||||
} else {
|
||||
let layout = Layout::from_size_align_unchecked(n, 1);
|
||||
|
|
|
@ -1,23 +1,9 @@
|
|||
use core::ptr;
|
||||
use core::slice;
|
||||
|
||||
use super::super::utils::memcpy_16;
|
||||
use super::super::Buffer;
|
||||
use super::{ESCAPED, ESCAPED_LEN, ESCAPE_LUT};
|
||||
|
||||
#[cfg(sailfish_nightly)]
|
||||
macro_rules! unlikely {
|
||||
($val:expr) => {
|
||||
std::intrinsics::unlikely($val)
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(not(sailfish_nightly))]
|
||||
macro_rules! unlikely {
|
||||
($val:expr) => {
|
||||
$val
|
||||
};
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super) unsafe fn escape(
|
||||
buffer: &mut Buffer,
|
||||
|
@ -27,7 +13,7 @@ pub(super) unsafe fn escape(
|
|||
) {
|
||||
start_ptr = proceed(buffer, start_ptr, ptr, end_ptr);
|
||||
|
||||
if end_ptr > start_ptr {
|
||||
if likely!(end_ptr > start_ptr) {
|
||||
let slc = slice::from_raw_parts(start_ptr, end_ptr as usize - start_ptr as usize);
|
||||
buffer.push_str(std::str::from_utf8_unchecked(slc));
|
||||
}
|
||||
|
@ -77,10 +63,10 @@ pub(super) unsafe fn escape_small(feed: &str, mut buf: *mut u8) -> usize {
|
|||
let slc =
|
||||
slice::from_raw_parts(start_ptr, ptr as usize - start_ptr as usize);
|
||||
|
||||
memcpy_small(slc.as_ptr(), buf, slc.len());
|
||||
memcpy_16(slc.as_ptr(), buf, slc.len());
|
||||
buf = buf.add(slc.len());
|
||||
}
|
||||
memcpy_small(escaped.as_ptr(), buf, escaped.len());
|
||||
memcpy_16(escaped.as_ptr(), buf, escaped.len());
|
||||
buf = buf.add(escaped.len());
|
||||
start_ptr = ptr.add(1);
|
||||
}
|
||||
|
@ -90,40 +76,11 @@ pub(super) unsafe fn escape_small(feed: &str, mut buf: *mut u8) -> usize {
|
|||
debug_assert_eq!(ptr, end_ptr);
|
||||
debug_assert!(start_ptr <= ptr);
|
||||
|
||||
if end_ptr > start_ptr {
|
||||
if likely!(end_ptr > start_ptr) {
|
||||
let slc = slice::from_raw_parts(start_ptr, end_ptr as usize - start_ptr as usize);
|
||||
memcpy_small(slc.as_ptr(), buf, slc.len());
|
||||
memcpy_16(slc.as_ptr(), buf, slc.len());
|
||||
buf = buf.add(slc.len());
|
||||
}
|
||||
|
||||
buf as usize - buf_begin as usize
|
||||
}
|
||||
|
||||
/// memcpy implementation based on glibc (https://github.molgen.mpg.de/git-mirror/glibc/blob/master/sysdeps/x86_64/multiarch/memcpy-avx-unaligned.S)
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
unsafe fn memcpy_small(src: *const u8, dst: *mut u8, len: usize) {
|
||||
debug_assert!(len <= 16);
|
||||
let len_u8 = len as u8;
|
||||
|
||||
if len_u8 >= 8 {
|
||||
let offset = len - 8;
|
||||
let t2 = ptr::read_unaligned(src.add(offset) as *const u64);
|
||||
let t1 = ptr::read_unaligned(src as *const u64);
|
||||
ptr::write_unaligned(dst.add(offset) as *mut u64, t2);
|
||||
ptr::write_unaligned(dst as *mut u64, t1);
|
||||
} else if len_u8 >= 4 {
|
||||
let offset = len - 4;
|
||||
let t2 = ptr::read_unaligned(src.add(offset) as *const u32);
|
||||
let t1 = ptr::read_unaligned(src as *const u32);
|
||||
ptr::write_unaligned(dst.add(offset) as *mut u32, t2);
|
||||
ptr::write_unaligned(dst as *mut u32, t1);
|
||||
} else if len_u8 >= 2 {
|
||||
let offset = len - 2;
|
||||
let t2 = ptr::read_unaligned(src.add(offset) as *const u16);
|
||||
let t1 = ptr::read_unaligned(src as *const u16);
|
||||
ptr::write_unaligned(dst.add(offset) as *mut u16, t2);
|
||||
ptr::write_unaligned(dst as *mut u16, t1);
|
||||
} else if len_u8 >= 1 {
|
||||
*dst = *src;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
//! Sailfish runtime
|
||||
|
||||
#[macro_use]
|
||||
mod utils;
|
||||
|
||||
mod buffer;
|
||||
pub mod escape;
|
||||
mod macros;
|
||||
|
|
|
@ -179,7 +179,7 @@ render_int!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, usize, isize);
|
|||
impl Render for f32 {
|
||||
#[cfg_attr(feature = "perf-inline", inline)]
|
||||
fn render(&self, b: &mut Buffer) -> Result<(), RenderError> {
|
||||
if self.is_finite() {
|
||||
if likely!(self.is_finite()) {
|
||||
unsafe {
|
||||
b.reserve(16);
|
||||
let ptr = b.as_mut_ptr().add(b.len());
|
||||
|
@ -208,7 +208,7 @@ impl Render for f32 {
|
|||
impl Render for f64 {
|
||||
#[cfg_attr(feature = "perf-inline", inline)]
|
||||
fn render(&self, b: &mut Buffer) -> Result<(), RenderError> {
|
||||
if self.is_finite() {
|
||||
if likely!(self.is_finite()) {
|
||||
unsafe {
|
||||
b.reserve(24);
|
||||
let ptr = b.as_mut_ptr().add(b.len());
|
||||
|
|
|
@ -26,7 +26,7 @@ impl SizeHint {
|
|||
#[inline]
|
||||
pub fn update(&self, mut value: usize) {
|
||||
value = value + value / 4;
|
||||
if self.get() < value {
|
||||
if unlikely!(self.get() < value) {
|
||||
self.value.store(value, Ordering::Release);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
use std::ptr;
|
||||
|
||||
#[cfg(sailfish_nightly)]
|
||||
macro_rules! likely {
|
||||
($val:expr) => {
|
||||
std::intrinsics::likely($val)
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(not(sailfish_nightly))]
|
||||
macro_rules! likely {
|
||||
($val:expr) => {
|
||||
$val
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(sailfish_nightly)]
|
||||
macro_rules! unlikely {
|
||||
($val:expr) => {
|
||||
std::intrinsics::unlikely($val)
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(not(sailfish_nightly))]
|
||||
macro_rules! unlikely {
|
||||
($val:expr) => {
|
||||
$val
|
||||
};
|
||||
}
|
||||
|
||||
/// memcpy implementation based on glibc (https://github.molgen.mpg.de/git-mirror/glibc/blob/master/sysdeps/x86_64/multiarch/memcpy-avx-unaligned.S)
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
pub unsafe fn memcpy_16(src: *const u8, dst: *mut u8, len: usize) {
|
||||
debug_assert!(len <= 16);
|
||||
let len_u8 = len as u8;
|
||||
|
||||
if len_u8 >= 8 {
|
||||
let offset = len - 8;
|
||||
let t2 = ptr::read_unaligned(src.add(offset) as *const u64);
|
||||
let t1 = ptr::read_unaligned(src as *const u64);
|
||||
ptr::write_unaligned(dst.add(offset) as *mut u64, t2);
|
||||
ptr::write_unaligned(dst as *mut u64, t1);
|
||||
} else if len_u8 >= 4 {
|
||||
let offset = len - 4;
|
||||
let t2 = ptr::read_unaligned(src.add(offset) as *const u32);
|
||||
let t1 = ptr::read_unaligned(src as *const u32);
|
||||
ptr::write_unaligned(dst.add(offset) as *mut u32, t2);
|
||||
ptr::write_unaligned(dst as *mut u32, t1);
|
||||
} else if len_u8 >= 2 {
|
||||
let offset = len - 2;
|
||||
let t2 = ptr::read_unaligned(src.add(offset) as *const u16);
|
||||
let t1 = ptr::read_unaligned(src as *const u16);
|
||||
ptr::write_unaligned(dst.add(offset) as *mut u16, t2);
|
||||
ptr::write_unaligned(dst as *mut u16, t1);
|
||||
} else if len_u8 >= 1 {
|
||||
*dst = *src;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue