forked from external-repos/squoosh
Merge pull request #746 from GoogleChromeLabs/fix-oxipng-free
Fix and document allocation shim for OxiPNG
This commit is contained in:
Binary file not shown.
@@ -2,6 +2,26 @@
|
|||||||
//! These implementations are compatible with the standard signatures
|
//! These implementations are compatible with the standard signatures
|
||||||
//! but use Rust allocator instead of including libc one as well.
|
//! but use Rust allocator instead of including libc one as well.
|
||||||
//!
|
//!
|
||||||
|
//! Rust allocator APIs requires passing size and alignment to the
|
||||||
|
//! `dealloc` function. This is different from C API, which only
|
||||||
|
//! expects a pointer in `free` and expects allocators to take care of
|
||||||
|
//! storing any necessary information elsewhere.
|
||||||
|
//!
|
||||||
|
//! In order to simulate C API, we allocate a `size_and_data_ptr`
|
||||||
|
//! of size `sizeof(usize) + size` where `size` is the requested number
|
||||||
|
//! of bytes. Then, we store `size` at the beginning of the allocated
|
||||||
|
//! chunk (within those `sizeof(usize)` bytes) and return
|
||||||
|
//! `data_ptr = size_and_data_ptr + sizeof(usize)` to the calleer:
|
||||||
|
//!
|
||||||
|
//! [`size`][...actual data]
|
||||||
|
//! -^------------------ `size_and_data_ptr`
|
||||||
|
//! ---------^---------- `data_ptr`
|
||||||
|
//!
|
||||||
|
//! Then, in `free`, the caller gives us `data_ptr`. We can subtract
|
||||||
|
//! `sizeof(usize)` back and get the original `size_and_data_ptr`.
|
||||||
|
//! At this point we can read `size` back and call the Rust `dealloc`
|
||||||
|
//! for the whole allocated chunk.
|
||||||
|
//!
|
||||||
//! I've raised an upstream issue to hopefully make this easier in
|
//! I've raised an upstream issue to hopefully make this easier in
|
||||||
//! future: https://github.com/ebiggers/libdeflate/issues/62
|
//! future: https://github.com/ebiggers/libdeflate/issues/62
|
||||||
|
|
||||||
@@ -20,8 +40,8 @@ pub unsafe extern "C" fn malloc(size: usize) -> *mut u8 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn free(ptr: *mut u8) {
|
pub unsafe extern "C" fn free(data_ptr: *mut u8) {
|
||||||
let size_and_data_ptr = ptr.sub(size_of::<usize>());
|
let size_and_data_ptr = data_ptr.sub(size_of::<usize>());
|
||||||
let size = *(size_and_data_ptr as *const usize);
|
let size = *(size_and_data_ptr as *const usize);
|
||||||
dealloc(ptr, layout_for(size))
|
dealloc(size_and_data_ptr, layout_for(size))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user