mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
FreeType: don’t use usable_size() as deallocation size
Instead use C-level malloc()/free() so that the size doesn’t need to be known during deallocation, since FreeType doesn’t provide it. Hopefully fixes https://github.com/servo/servo/issues/19058
This commit is contained in:
parent
1b73cf3352
commit
6319ad0124
4 changed files with 37 additions and 50 deletions
15
Cargo.lock
generated
15
Cargo.lock
generated
|
@ -1447,7 +1447,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jemalloc-sys"
|
name = "jemalloc-sys"
|
||||||
version = "0.1.3"
|
version = "0.1.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cc 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1456,10 +1456,10 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jemallocator"
|
name = "jemallocator"
|
||||||
version = "0.1.3"
|
version = "0.1.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"jemalloc-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"jemalloc-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2391,7 +2391,7 @@ dependencies = [
|
||||||
"heartbeats-simple 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"heartbeats-simple 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"influent 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"influent 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ipc-channel 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ipc-channel 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"jemalloc-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"jemalloc-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"profile_traits 0.0.1",
|
"profile_traits 0.0.1",
|
||||||
|
@ -2956,8 +2956,9 @@ dependencies = [
|
||||||
name = "servo_allocator"
|
name = "servo_allocator"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"jemallocator 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"jemallocator 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3912,8 +3913,8 @@ dependencies = [
|
||||||
"checksum ipc-channel 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c10ed089b1921b01ef342c736a37ee0788eeb9a5f373bb2df1ba88d01125064f"
|
"checksum ipc-channel 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c10ed089b1921b01ef342c736a37ee0788eeb9a5f373bb2df1ba88d01125064f"
|
||||||
"checksum itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc"
|
"checksum itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc"
|
||||||
"checksum itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2f404fbc66fd9aac13e998248505e7ecb2ad8e44ab6388684c5fb11c6c251c"
|
"checksum itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2f404fbc66fd9aac13e998248505e7ecb2ad8e44ab6388684c5fb11c6c251c"
|
||||||
"checksum jemalloc-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94fb624d7e8345e5c42caab8d1db6ec925fdadff3fd0cb7dd781b41be8442828"
|
"checksum jemalloc-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "479294d130502fada93c7a957e8d059b632b03d6204aca37af557dee947f30a9"
|
||||||
"checksum jemallocator 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1850725977c344d63af66e8fd00857646e3ec936c490cd63667860b7b03ab5c1"
|
"checksum jemallocator 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "28b211ca65c440322b6d4d9b5b850b01e8e298393b7ebcb8205b7cbb14ea6329"
|
||||||
"checksum jpeg-decoder 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2805ccb10ffe4d10e06ef68a158ff94c255211ecbae848fbde2146b098f93ce7"
|
"checksum jpeg-decoder 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2805ccb10ffe4d10e06ef68a158ff94c255211ecbae848fbde2146b098f93ce7"
|
||||||
"checksum js 0.1.6 (git+https://github.com/servo/rust-mozjs)" = "<none>"
|
"checksum js 0.1.6 (git+https://github.com/servo/rust-mozjs)" = "<none>"
|
||||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||||
|
|
|
@ -11,8 +11,11 @@ path = "lib.rs"
|
||||||
[features]
|
[features]
|
||||||
unstable = ["kernel32-sys", "jemallocator"]
|
unstable = ["kernel32-sys", "jemallocator"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
libc = "0.2" # Only used when 'unstable' is disabled, but looks like Cargo cannot express that.
|
||||||
|
|
||||||
[target.'cfg(not(windows))'.dependencies]
|
[target.'cfg(not(windows))'.dependencies]
|
||||||
jemallocator = { version = "0.1.3", optional = true }
|
jemallocator = { version = "0.1.4", optional = true }
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
kernel32-sys = { version = "0.2.1", optional = true }
|
kernel32-sys = { version = "0.2.1", optional = true }
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
|
|
||||||
#[cfg(feature = "unstable")]
|
#[cfg(feature = "unstable")]
|
||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
static ALLOC: platform::Allocator = platform::Allocator;
|
static ALLOC: Allocator = Allocator;
|
||||||
|
|
||||||
pub use platform::usable_size;
|
pub use platform::*;
|
||||||
|
|
||||||
|
|
||||||
#[cfg(all(feature = "unstable", not(windows)))]
|
#[cfg(all(feature = "unstable", not(windows)))]
|
||||||
|
@ -25,6 +25,11 @@ mod platform {
|
||||||
pub unsafe extern "C" fn usable_size(ptr: *const c_void) -> usize {
|
pub unsafe extern "C" fn usable_size(ptr: *const c_void) -> usize {
|
||||||
jemallocator::usable_size(ptr)
|
jemallocator::usable_size(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Memory allocation APIs compatible with libc
|
||||||
|
pub mod libc_compat {
|
||||||
|
pub use super::jemallocator::ffi::{malloc, realloc, free};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(feature = "unstable", windows))]
|
#[cfg(all(feature = "unstable", windows))]
|
||||||
|
@ -57,6 +62,10 @@ mod platform {
|
||||||
pub unsafe extern "C" fn usable_size(_ptr: *const c_void) -> usize {
|
pub unsafe extern "C" fn usable_size(_ptr: *const c_void) -> usize {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Memory allocation APIs compatible with libc
|
||||||
|
pub mod libc_compat {
|
||||||
|
extern crate libc;
|
||||||
|
pub use self::libc::{malloc, realloc, free};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,8 @@ use freetype::freetype::FT_Memory;
|
||||||
use freetype::freetype::FT_MemoryRec_;
|
use freetype::freetype::FT_MemoryRec_;
|
||||||
use freetype::freetype::FT_New_Library;
|
use freetype::freetype::FT_New_Library;
|
||||||
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
||||||
|
use servo_allocator::libc_compat::{malloc, realloc, free};
|
||||||
use servo_allocator::usable_size;
|
use servo_allocator::usable_size;
|
||||||
use std::mem;
|
|
||||||
use std::os::raw::{c_long, c_void};
|
use std::os::raw::{c_long, c_void};
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
@ -22,65 +22,39 @@ pub struct User {
|
||||||
size: usize,
|
size: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
// FreeType doesn't require any particular alignment for allocations.
|
|
||||||
const FT_ALIGNMENT: usize = 1;
|
|
||||||
|
|
||||||
extern fn ft_alloc(mem: FT_Memory, req_size: c_long) -> *mut c_void {
|
extern fn ft_alloc(mem: FT_Memory, req_size: c_long) -> *mut c_void {
|
||||||
assert!(FT_ALIGNMENT == 1);
|
|
||||||
let mut vec = Vec::<u8>::with_capacity(req_size as usize);
|
|
||||||
let ptr = vec.as_mut_ptr() as *mut c_void;
|
|
||||||
mem::forget(vec);
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let actual_size = usable_size(ptr as *const _);
|
let ptr = malloc(req_size as usize);
|
||||||
|
let ptr = ptr as *mut c_void; // libc::c_void vs std::os::raw::c_void
|
||||||
|
let actual_size = usable_size(ptr);
|
||||||
let user = (*mem).user as *mut User;
|
let user = (*mem).user as *mut User;
|
||||||
(*user).size += actual_size;
|
(*user).size += actual_size;
|
||||||
}
|
|
||||||
|
|
||||||
ptr
|
ptr
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extern fn ft_free(mem: FT_Memory, ptr: *mut c_void) {
|
extern fn ft_free(mem: FT_Memory, ptr: *mut c_void) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let actual_size = usable_size(ptr as *const _);
|
let actual_size = usable_size(ptr);
|
||||||
let user = (*mem).user as *mut User;
|
let user = (*mem).user as *mut User;
|
||||||
(*user).size -= actual_size;
|
(*user).size -= actual_size;
|
||||||
|
free(ptr as *mut _);
|
||||||
assert!(FT_ALIGNMENT == 1);
|
|
||||||
mem::drop(Vec::<u8>::from_raw_parts(ptr as *mut u8, actual_size, 0))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern fn ft_realloc(mem: FT_Memory, _old_size: c_long, new_req_size: c_long,
|
extern fn ft_realloc(mem: FT_Memory, _old_size: c_long, new_req_size: c_long,
|
||||||
old_ptr: *mut c_void) -> *mut c_void {
|
old_ptr: *mut c_void) -> *mut c_void {
|
||||||
let old_actual_size;
|
|
||||||
let mut vec;
|
|
||||||
unsafe {
|
unsafe {
|
||||||
old_actual_size = usable_size(old_ptr as *const _);
|
let old_actual_size = usable_size(old_ptr);
|
||||||
let old_size = old_actual_size as usize;
|
let new_ptr = realloc(old_ptr as *mut _, new_req_size as usize);
|
||||||
vec = Vec::<u8>::from_raw_parts(old_ptr as *mut u8, old_size, old_size);
|
let new_ptr = new_ptr as *mut c_void;
|
||||||
};
|
let new_actual_size = usable_size(new_ptr);
|
||||||
|
|
||||||
let new_req_size = new_req_size as usize;
|
|
||||||
if new_req_size > old_actual_size {
|
|
||||||
vec.reserve_exact(new_req_size - old_actual_size)
|
|
||||||
} else if new_req_size < old_actual_size {
|
|
||||||
vec.truncate(new_req_size);
|
|
||||||
vec.shrink_to_fit()
|
|
||||||
}
|
|
||||||
|
|
||||||
let new_ptr = vec.as_mut_ptr() as *mut c_void;
|
|
||||||
mem::forget(vec);
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let new_actual_size = usable_size(new_ptr as *const _);
|
|
||||||
let user = (*mem).user as *mut User;
|
let user = (*mem).user as *mut User;
|
||||||
(*user).size += new_actual_size;
|
(*user).size += new_actual_size;
|
||||||
(*user).size -= old_actual_size;
|
(*user).size -= old_actual_size;
|
||||||
}
|
|
||||||
|
|
||||||
new_ptr
|
new_ptr
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// A |*mut User| field in a struct triggers a "use of `#[derive]` with a raw pointer" warning from
|
// A |*mut User| field in a struct triggers a "use of `#[derive]` with a raw pointer" warning from
|
||||||
// rustc. But using a typedef avoids this, so...
|
// rustc. But using a typedef avoids this, so...
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue