diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index e8744a17790..001b29dd53b 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -1291,6 +1291,7 @@ name = "util_tests" version = "0.0.1" dependencies = [ "geom 0.1.0 (git+https://github.com/servo/rust-geom)", + "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "plugins 0.0.1", "util 0.0.1", ] diff --git a/tests/unit/util/Cargo.toml b/tests/unit/util/Cargo.toml index f6adbaca25d..21edb79c613 100644 --- a/tests/unit/util/Cargo.toml +++ b/tests/unit/util/Cargo.toml @@ -17,3 +17,7 @@ path = "../../../components/plugins" [dependencies.geom] git = "https://github.com/servo/rust-geom" + +[dependencies] +libc = "*" + diff --git a/tests/unit/util/lib.rs b/tests/unit/util/lib.rs index 2048c2a0b57..badcbd40e7a 100644 --- a/tests/unit/util/lib.rs +++ b/tests/unit/util/lib.rs @@ -2,9 +2,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#![feature(plugin, custom_derive, custom_attributes)] +#![feature(plugin, custom_derive, alloc)] #![plugin(plugins)] extern crate util; +extern crate libc; extern crate geom; #[cfg(test)] mod cache; diff --git a/tests/unit/util/mem.rs b/tests/unit/util/mem.rs index 8ad01063809..ff25ded0b31 100644 --- a/tests/unit/util/mem.rs +++ b/tests/unit/util/mem.rs @@ -2,8 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use util::mem::HeapSizeOf; - +use libc::c_void; +use util::mem::{HeapSizeOf, heap_size_of}; struct Four; impl HeapSizeOf for Four { @@ -24,6 +24,81 @@ enum EightOrFour { #[test] fn test_heap_size() { + + // Note: jemalloc often rounds up request sizes. However, it does not round up for request + // sizes of 8 and higher that are powers of two. We take advantage of knowledge here to make + // the sizes of various heap-allocated blocks predictable. + + //----------------------------------------------------------------------- + // Start with basic heap block measurement. + + unsafe { + // EMPTY is the special non-null address used to represent zero-size allocations. + assert_eq!(heap_size_of(::std::rt::heap::EMPTY as *const c_void), 0); + + // A 64 byte request is allocated exactly. + let x = ::std::rt::heap::allocate(64, 0); + assert_eq!(heap_size_of(x as *const c_void), 64); + ::std::rt::heap::deallocate(x, 64, 0); + + // A 255 byte request is rounded up to 256 bytes. + let x = ::std::rt::heap::allocate(255, 0); + assert_eq!(heap_size_of(x as *const c_void), 256); + ::std::rt::heap::deallocate(x, 255, 0); + + // A 1MiB request is allocated exactly. + let x = ::std::rt::heap::allocate(1024 * 1024, 0); + assert_eq!(heap_size_of(x as *const c_void), 1024 * 1024); + ::std::rt::heap::deallocate(x, 1024 * 1024, 0); + } + + //----------------------------------------------------------------------- + // Test HeapSizeOf implementations for various built-in types. + + // Not on the heap; 0 bytes. + let x = 0i64; + assert_eq!(x.heap_size_of_children(), 0); + + // An i64 is 8 bytes. + let x = Box::new(0i64); + assert_eq!(x.heap_size_of_children(), 8); + + // An ascii string with 16 chars is 16 bytes in UTF-8. + let mut x = String::new(); + x.push_str("0123456789abcdef"); + assert_eq!(x.heap_size_of_children(), 16); + + // Not on the heap. + let x: Option = None; + assert_eq!(x.heap_size_of_children(), 0); + + // Not on the heap. + let x = Some(0i64); + assert_eq!(x.heap_size_of_children(), 0); + + // The `Some` is not on the heap, but the Box is. + let x = Some(Box::new(0i64)); + assert_eq!(x.heap_size_of_children(), 8); + + // Not on the heap. + let x = ::std::sync::Arc::new(0i64); + assert_eq!(x.heap_size_of_children(), 0); + + // The `Arc` is not on the heap, but the Box is. + let x = ::std::sync::Arc::new(Box::new(0i64)); + assert_eq!(x.heap_size_of_children(), 8); + + // Zero elements, no heap storage. + let x: Vec = vec![]; + assert_eq!(x.heap_size_of_children(), 0); + + // Four elements, 8 bytes per element. + let x = vec![0i64, 1i64, 2i64, 3i64]; + assert_eq!(x.heap_size_of_children(), 32); + + //----------------------------------------------------------------------- + // Test the HeapSizeOf auto-deriving. + assert_eq!(Four.heap_size_of_children(), 4); let eight = Eight(Four, Four, true, true, true); assert_eq!(eight.heap_size_of_children(), 8);