refactor: Add utils.rs

This commit is contained in:
Kogia-sima 2020-07-11 04:23:39 +09:00
parent 5cef362dbd
commit b4903f2b3d
6 changed files with 71 additions and 67 deletions

View File

@ -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);

View File

@ -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;
}
}

View File

@ -1,5 +1,8 @@
//! Sailfish runtime
#[macro_use]
mod utils;
mod buffer;
pub mod escape;
mod macros;

View File

@ -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());

View File

@ -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);
}
}

View File

@ -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;
}
}