mirror of
https://github.com/servo/servo.git
synced 2025-07-23 15:23:42 +01:00
fallible: Avoid using system malloc in servo.
This commit is contained in:
parent
c85633f48e
commit
6661bfa838
3 changed files with 32 additions and 9 deletions
|
@ -12,3 +12,14 @@ path = "lib.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
smallvec = "0.4"
|
smallvec = "0.4"
|
||||||
hashglobe = { path = "../hashglobe" }
|
hashglobe = { path = "../hashglobe" }
|
||||||
|
|
||||||
|
# This crate effectively does nothing except if the `known_system_malloc`
|
||||||
|
# feature is specified.
|
||||||
|
#
|
||||||
|
# In that case, we actually call the system malloc functions to reserve space,
|
||||||
|
# otherwise we just let rust do its thing (aborting on OOM).
|
||||||
|
#
|
||||||
|
# This is effectively a stop-gap measure until we can do this properly in
|
||||||
|
# stable rust.
|
||||||
|
[features]
|
||||||
|
known_system_malloc = []
|
||||||
|
|
|
@ -8,10 +8,9 @@ extern crate smallvec;
|
||||||
use hashglobe::FailedAllocationError;
|
use hashglobe::FailedAllocationError;
|
||||||
use smallvec::Array;
|
use smallvec::Array;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::mem;
|
|
||||||
use std::ptr::copy_nonoverlapping;
|
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
|
|
||||||
|
#[cfg(feature = "known_system_malloc")]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn realloc(ptr: *mut u8, bytes: usize) -> *mut u8;
|
fn realloc(ptr: *mut u8, bytes: usize) -> *mut u8;
|
||||||
fn malloc(bytes: usize) -> *mut u8;
|
fn malloc(bytes: usize) -> *mut u8;
|
||||||
|
@ -30,10 +29,13 @@ pub trait FallibleVec<T> {
|
||||||
impl<T> FallibleVec<T> for Vec<T> {
|
impl<T> FallibleVec<T> for Vec<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn try_push(&mut self, val: T) -> Result<(), FailedAllocationError> {
|
fn try_push(&mut self, val: T) -> Result<(), FailedAllocationError> {
|
||||||
|
#[cfg(feature = "known_system_malloc")]
|
||||||
|
{
|
||||||
if self.capacity() == self.len() {
|
if self.capacity() == self.len() {
|
||||||
try_double_vec(self)?;
|
try_double_vec(self)?;
|
||||||
debug_assert!(self.capacity() > self.len());
|
debug_assert!(self.capacity() > self.len());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
self.push(val);
|
self.push(val);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -41,9 +43,12 @@ impl<T> FallibleVec<T> for Vec<T> {
|
||||||
|
|
||||||
// Double the capacity of |vec|, or fail to do so due to lack of memory.
|
// Double the capacity of |vec|, or fail to do so due to lack of memory.
|
||||||
// Returns Ok(()) on success, Err(..) on failure.
|
// Returns Ok(()) on success, Err(..) on failure.
|
||||||
|
#[cfg(feature = "known_system_malloc")]
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
#[cold]
|
#[cold]
|
||||||
fn try_double_vec<T>(vec: &mut Vec<T>) -> Result<(), FailedAllocationError> {
|
fn try_double_vec<T>(vec: &mut Vec<T>) -> Result<(), FailedAllocationError> {
|
||||||
|
use std::mem;
|
||||||
|
|
||||||
let old_ptr = vec.as_mut_ptr();
|
let old_ptr = vec.as_mut_ptr();
|
||||||
let old_len = vec.len();
|
let old_len = vec.len();
|
||||||
|
|
||||||
|
@ -89,10 +94,13 @@ fn try_double_vec<T>(vec: &mut Vec<T>) -> Result<(), FailedAllocationError> {
|
||||||
impl<T: Array> FallibleVec<T::Item> for SmallVec<T> {
|
impl<T: Array> FallibleVec<T::Item> for SmallVec<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn try_push(&mut self, val: T::Item) -> Result<(), FailedAllocationError> {
|
fn try_push(&mut self, val: T::Item) -> Result<(), FailedAllocationError> {
|
||||||
|
#[cfg(feature = "known_system_malloc")]
|
||||||
|
{
|
||||||
if self.capacity() == self.len() {
|
if self.capacity() == self.len() {
|
||||||
try_double_small_vec(self)?;
|
try_double_small_vec(self)?;
|
||||||
debug_assert!(self.capacity() > self.len());
|
debug_assert!(self.capacity() > self.len());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
self.push(val);
|
self.push(val);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -100,6 +108,7 @@ impl<T: Array> FallibleVec<T::Item> for SmallVec<T> {
|
||||||
|
|
||||||
// Double the capacity of |svec|, or fail to do so due to lack of memory.
|
// Double the capacity of |svec|, or fail to do so due to lack of memory.
|
||||||
// Returns Ok(()) on success, Err(..) on failure.
|
// Returns Ok(()) on success, Err(..) on failure.
|
||||||
|
#[cfg(feature = "known_system_malloc")]
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
#[cold]
|
#[cold]
|
||||||
fn try_double_small_vec<T>(svec: &mut SmallVec<T>)
|
fn try_double_small_vec<T>(svec: &mut SmallVec<T>)
|
||||||
|
@ -107,6 +116,9 @@ fn try_double_small_vec<T>(svec: &mut SmallVec<T>)
|
||||||
where
|
where
|
||||||
T: Array,
|
T: Array,
|
||||||
{
|
{
|
||||||
|
use std::mem;
|
||||||
|
use std::ptr::copy_nonoverlapping;
|
||||||
|
|
||||||
let old_ptr = svec.as_mut_ptr();
|
let old_ptr = svec.as_mut_ptr();
|
||||||
let old_len = svec.len();
|
let old_len = svec.len();
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ path = "lib.rs"
|
||||||
doctest = false
|
doctest = false
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
gecko = ["nsstring_vendor", "num_cpus", "style_traits/gecko"]
|
gecko = ["nsstring_vendor", "num_cpus", "style_traits/gecko", "fallible/known_system_malloc"]
|
||||||
use_bindgen = ["bindgen", "regex", "toml"]
|
use_bindgen = ["bindgen", "regex", "toml"]
|
||||||
servo = ["serde", "heapsize", "heapsize_derive",
|
servo = ["serde", "heapsize", "heapsize_derive",
|
||||||
"style_traits/servo", "servo_atoms", "servo_config", "html5ever",
|
"style_traits/servo", "servo_atoms", "servo_config", "html5ever",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue