servo: Merge #20433 - Statically allocate static atoms (from nnethercote:bug-1411469); r=froydnj

<!-- Please describe your changes on the following line: -->

This is the Servo part of bug 1411469.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix Mozilla bug 1411469

<!-- Either: -->
- [ ] There are tests for these changes OR
- [X] These changes do not require tests because tests are on the Gecko side.

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

r? @emilio

Source-Repo: https://github.com/servo/servo
Source-Revision: 10813436b36323711430ab56fad83234029c9f96

--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 26652a48385035c413b0290768cbefee37b765e9
This commit is contained in:
Nicholas Nethercote 2018-03-26 04:08:14 -04:00
parent 051a0fc278
commit 1c6665e18b
2 changed files with 58 additions and 23 deletions

View File

@ -17188,26 +17188,25 @@ pub mod root {
pub struct nsAtom {
pub _bitfield_1: root::__BindgenBitfieldUnit<[u8; 4usize], u32>,
pub mHash: u32,
pub mString: *const u16,
}
#[repr(u8)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum nsAtom_AtomKind {
DynamicAtom = 0,
StaticAtom = 1,
HTML5Atom = 2,
Static = 0,
DynamicNormal = 1,
DynamicHTML5 = 2,
}
pub type nsAtom_HasThreadSafeRefCnt = root::mozilla::TrueType;
#[test]
fn bindgen_test_layout_nsAtom() {
assert_eq!(
::std::mem::size_of::<nsAtom>(),
16usize,
8usize,
concat!("Size of: ", stringify!(nsAtom))
);
assert_eq!(
::std::mem::align_of::<nsAtom>(),
8usize,
4usize,
concat!("Alignment of ", stringify!(nsAtom))
);
assert_eq!(
@ -17220,16 +17219,6 @@ pub mod root {
stringify!(mHash)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<nsAtom>())).mString as *const _ as usize },
8usize,
concat!(
"Offset of field: ",
stringify!(nsAtom),
"::",
stringify!(mString)
)
);
}
impl nsAtom {
#[inline]
@ -17278,19 +17267,55 @@ pub mod root {
#[derive(Debug)]
pub struct nsStaticAtom {
pub _base: root::nsAtom,
pub mStringOffset: u32,
}
#[test]
fn bindgen_test_layout_nsStaticAtom() {
assert_eq!(
::std::mem::size_of::<nsStaticAtom>(),
16usize,
12usize,
concat!("Size of: ", stringify!(nsStaticAtom))
);
assert_eq!(
::std::mem::align_of::<nsStaticAtom>(),
8usize,
4usize,
concat!("Alignment of ", stringify!(nsStaticAtom))
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<nsStaticAtom>())).mStringOffset as *const _ as usize },
8usize,
concat!("Offset of field: ", stringify!(nsStaticAtom), "::", stringify!(mString))
);
}
#[repr(C)]
#[derive(Debug)]
pub struct nsDynamicAtom {
pub _base: root::nsAtom,
pub mRefCnt: root::mozilla::ThreadSafeAutoRefCnt,
pub mString: *const u16,
}
#[test]
fn bindgen_test_layout_nsDynamicAtom() {
assert_eq!(
::std::mem::size_of::<nsDynamicAtom>(),
24usize,
concat!("Size of: ", stringify!(nsDynamicAtom))
);
assert_eq!(
::std::mem::align_of::<nsDynamicAtom>(),
8usize,
concat!("Alignment of ", stringify!(nsDynamicAtom))
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<nsDynamicAtom>())).mRefCnt as *const _ as usize },
8usize,
concat!("Offset of field: ", stringify!(nsDynamicAtom), "::", stringify!(mRefCnt))
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<nsDynamicAtom>())).mString as *const _ as usize },
16usize,
concat!("Offset of field: ", stringify!(nsDynamicAtom), "::", stringify!(mString))
);
}
pub type nsLoadFlags = u32;
#[repr(C)]

View File

@ -10,7 +10,7 @@ use gecko_bindings::bindings::Gecko_AddRefAtom;
use gecko_bindings::bindings::Gecko_Atomize;
use gecko_bindings::bindings::Gecko_Atomize16;
use gecko_bindings::bindings::Gecko_ReleaseAtom;
use gecko_bindings::structs::{nsAtom, nsAtom_AtomKind, nsStaticAtom};
use gecko_bindings::structs::{nsAtom, nsAtom_AtomKind, nsDynamicAtom, nsStaticAtom};
use nsstring::{nsAString, nsStr};
use precomputed_hash::PrecomputedHash;
use std::{mem, slice, str};
@ -113,9 +113,19 @@ impl WeakAtom {
/// Get the atom as a slice of utf-16 chars.
#[inline]
pub fn as_slice(&self) -> &[u16] {
unsafe {
slice::from_raw_parts((*self.as_ptr()).mString, self.len() as usize)
}
let string = if self.is_static() {
let atom_ptr = self.as_ptr() as *const nsStaticAtom;
let string_offset = unsafe { (*atom_ptr).mStringOffset };
let string_offset = -(string_offset as isize);
let u8_ptr = atom_ptr as *const u8;
// It is safe to use offset() here because both addresses are within
// the same struct, e.g. mozilla::detail::gGkAtoms.
unsafe { u8_ptr.offset(string_offset) as *const u16 }
} else {
let atom_ptr = self.as_ptr() as *const nsDynamicAtom;
unsafe { (*(atom_ptr)).mString }
};
unsafe { slice::from_raw_parts(string, self.len() as usize) }
}
// NOTE: don't expose this, since it's slow, and easy to be misused.
@ -166,7 +176,7 @@ impl WeakAtom {
#[inline]
pub fn is_static(&self) -> bool {
unsafe {
(*self.as_ptr()).mKind() == nsAtom_AtomKind::StaticAtom as u32
(*self.as_ptr()).mKind() == nsAtom_AtomKind::Static as u32
}
}