Skip to content

Commit 8e31b82

Browse files
author
bors-servo
authored
Auto merge of #192 - servo:big, r=nox
Support big-endian platforms Fixes #191. <!-- Reviewable:start --> This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/string-cache/192) <!-- Reviewable:end -->
2 parents 3b1bcf8 + c8ebbfb commit 8e31b82

File tree

1 file changed

+28
-35
lines changed

1 file changed

+28
-35
lines changed

src/atom.rs

Lines changed: 28 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ use std::hash::{Hash, Hasher};
2323
use std::marker::PhantomData;
2424
use std::mem;
2525
use std::ops;
26-
use std::ptr;
2726
use std::slice;
2827
use std::str;
2928
use std::sync::Mutex;
@@ -314,7 +313,7 @@ impl<'a, Static: StaticAtomSet> From<Cow<'a, str>> for Atom<Static> {
314313
let len = string_to_add.len();
315314
if len <= MAX_INLINE_LEN {
316315
let mut buf: [u8; 7] = [0; 7];
317-
copy_memory(string_to_add.as_bytes(), &mut buf);
316+
buf[..len].copy_from_slice(string_to_add.as_bytes());
318317
Inline(len as u8, buf)
319318
} else {
320319
Dynamic(STRING_CACHE.lock().unwrap().add(string_to_add, hash) as *mut ())
@@ -528,18 +527,31 @@ enum UnpackedAtom {
528527
Static(u32),
529528
}
530529

531-
struct RawSlice {
532-
data: *const u8,
533-
len: usize,
530+
#[inline(always)]
531+
fn inline_atom_slice(x: &u64) -> &[u8] {
532+
unsafe {
533+
let x: *const u64 = x;
534+
let mut data = x as *const u8;
535+
// All except the lowest byte, which is first in little-endian, last in big-endian.
536+
if cfg!(target_endian = "little") {
537+
data = data.offset(1);
538+
}
539+
let len = 7;
540+
slice::from_raw_parts(data, len)
541+
}
534542
}
535543

536-
#[cfg(target_endian = "little")] // Not implemented yet for big-endian
537544
#[inline(always)]
538-
unsafe fn inline_atom_slice(x: &u64) -> RawSlice {
539-
let x: *const u64 = x;
540-
RawSlice {
541-
data: (x as *const u8).offset(1),
542-
len: 7,
545+
fn inline_atom_slice_mut(x: &mut u64) -> &mut [u8] {
546+
unsafe {
547+
let x: *mut u64 = x;
548+
let mut data = x as *mut u8;
549+
// All except the lowest byte, which is first in little-endian, last in big-endian.
550+
if cfg!(target_endian = "little") {
551+
data = data.offset(1);
552+
}
553+
let len = 7;
554+
slice::from_raw_parts_mut(data, len)
543555
}
544556
}
545557

@@ -557,10 +569,8 @@ impl UnpackedAtom {
557569
debug_assert!((len as usize) <= MAX_INLINE_LEN);
558570
let mut data: u64 = (INLINE_TAG as u64) | ((len as u64) << 4);
559571
{
560-
let raw_slice = inline_atom_slice(&mut data);
561-
let dest: &mut [u8] = slice::from_raw_parts_mut(
562-
raw_slice.data as *mut u8, raw_slice.len);
563-
copy_memory(&buf[..], dest);
572+
let dest = inline_atom_slice_mut(&mut data);
573+
dest.copy_from_slice(&buf)
564574
}
565575
data
566576
}
@@ -578,9 +588,8 @@ impl UnpackedAtom {
578588
let len = ((data & 0xf0) >> 4) as usize;
579589
debug_assert!(len <= MAX_INLINE_LEN);
580590
let mut buf: [u8; 7] = [0; 7];
581-
let raw_slice = inline_atom_slice(&data);
582-
let src: &[u8] = slice::from_raw_parts(raw_slice.data, raw_slice.len);
583-
copy_memory(src, &mut buf[..]);
591+
let src = inline_atom_slice(&data);
592+
buf.copy_from_slice(src);
584593
Inline(len as u8, buf)
585594
},
586595
_ => debug_unreachable!(),
@@ -606,29 +615,13 @@ unsafe fn from_packed_dynamic(data: u64) -> Option<*mut ()> {
606615
unsafe fn inline_orig_bytes<'a>(data: &'a u64) -> &'a [u8] {
607616
match UnpackedAtom::from_packed(*data) {
608617
Inline(len, _) => {
609-
let raw_slice = inline_atom_slice(&data);
610-
let src: &[u8] = slice::from_raw_parts(raw_slice.data, raw_slice.len);
618+
let src = inline_atom_slice(&data);
611619
&src[..(len as usize)]
612620
}
613621
_ => debug_unreachable!(),
614622
}
615623
}
616624

617-
618-
/// Copy of std::slice::bytes::copy_memory, which is unstable.
619-
#[inline]
620-
fn copy_memory(src: &[u8], dst: &mut [u8]) {
621-
let len_src = src.len();
622-
assert!(dst.len() >= len_src);
623-
// `dst` is unaliasable, so we know statically it doesn't overlap
624-
// with `src`.
625-
unsafe {
626-
ptr::copy_nonoverlapping(src.as_ptr(),
627-
dst.as_mut_ptr(),
628-
len_src);
629-
}
630-
}
631-
632625
#[cfg(test)]
633626
#[macro_use]
634627
mod tests {

0 commit comments

Comments
 (0)