Skip to content
This repository was archived by the owner on Jul 10, 2023. It is now read-only.

Commit 34229c3

Browse files
committed
Properly support Windows
We use HeapSize with GetProcessHeap() and flags 0, like Rust itself.
1 parent 7913872 commit 34229c3

File tree

2 files changed

+44
-20
lines changed

2 files changed

+44
-20
lines changed

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,8 @@ description = "Infrastructure for measuring the total runtime size of an object
66
license = "MPL-2.0"
77
repository = "https://github.com/servo/heapsize"
88

9+
[dependencies]
10+
kernel32-sys = "0.2.1"
11+
912
[features]
1013
unstable = []

src/lib.rs

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44

55
//! Data structure measurement.
66
7+
#[cfg(target_os = "windows")]
8+
extern crate kernel32;
9+
10+
#[cfg(target_os = "windows")]
11+
use kernel32::{GetProcessHeap, HeapSize, HeapValidate};
712
use std::borrow::Cow;
813
use std::cell::{Cell, RefCell};
914
use std::collections::{BTreeMap, HashMap, LinkedList, VecDeque};
@@ -18,38 +23,54 @@ use std::sync::Arc;
1823
use std::sync::atomic::{AtomicBool, AtomicIsize, AtomicUsize};
1924
use std::rc::Rc;
2025

21-
#[cfg(not(target_os = "windows"))]
22-
extern {
23-
// Get the size of a heap block.
24-
//
25-
// Ideally Rust would expose a function like this in std::rt::heap, which would avoid the
26-
// jemalloc dependence.
27-
//
28-
// The C prototype is `je_malloc_usable_size(JEMALLOC_USABLE_SIZE_CONST void *ptr)`. On some
29-
// platforms `JEMALLOC_USABLE_SIZE_CONST` is `const` and on some it is empty. But in practice
30-
// this function doesn't modify the contents of the block that `ptr` points to, so we use
31-
// `*const c_void` here.
32-
fn je_malloc_usable_size(ptr: *const c_void) -> usize;
33-
}
34-
35-
/// A wrapper for je_malloc_usable_size that handles `EMPTY` and returns `usize`.
26+
/// Get the size of a heap block.
27+
///
28+
/// Ideally Rust would expose a function like this in std::rt::heap, which would avoid the
29+
/// jemalloc dependence.
3630
///
3731
/// `unsafe` because the caller must ensure that the pointer is from jemalloc.
3832
/// FIXME: This probably interacts badly with custom allocators:
3933
/// https://doc.rust-lang.org/book/custom-allocators.html
40-
#[cfg(not(target_os = "windows"))]
4134
pub unsafe fn heap_size_of(ptr: *const c_void) -> usize {
4235
if ptr == 0x01 as *const c_void {
4336
0
4437
} else {
45-
je_malloc_usable_size(ptr)
38+
heap_size_of_impl(ptr)
4639
}
4740
}
4841

49-
/// FIXME: Need to implement heap size support on Windows.
42+
#[cfg(not(target_os = "windows"))]
43+
unsafe fn heap_size_of_impl(ptr: *const c_void) -> usize {
44+
// The C prototype is `je_malloc_usable_size(JEMALLOC_USABLE_SIZE_CONST void *ptr)`. On some
45+
// platforms `JEMALLOC_USABLE_SIZE_CONST` is `const` and on some it is empty. But in practice
46+
// this function doesn't modify the contents of the block that `ptr` points to, so we use
47+
// `*const c_void` here.
48+
extern "C" {
49+
fn je_malloc_usable_size(ptr: *const c_void) -> usize;
50+
}
51+
je_malloc_usable_size(ptr)
52+
}
53+
5054
#[cfg(target_os = "windows")]
51-
pub unsafe fn heap_size_of(ptr: *const c_void) -> usize {
52-
0
55+
pub unsafe fn heap_size_of_impl(mut ptr: *const c_void) -> usize {
56+
// Copied from Rust's liballoc_system.
57+
#[cfg(all(any(target_arch = "x86",
58+
target_arch = "arm",
59+
target_arch = "mips",
60+
target_arch = "mipsel",
61+
target_arch = "powerpc")))]
62+
const MIN_ALIGN: usize = 8;
63+
#[cfg(all(any(target_arch = "x86_64",
64+
target_arch = "aarch64")))]
65+
const MIN_ALIGN: usize = 16;
66+
67+
let heap = GetProcessHeap();
68+
69+
if ptr as usize % (MIN_ALIGN * 2) != 0 && HeapValidate(heap, 0, ptr) == 0 {
70+
ptr = *(ptr as *const *const c_void).offset(-1);
71+
}
72+
73+
HeapSize(heap, 0, ptr) as usize
5374
}
5475

5576
// The simplest trait for measuring the size of heap data structures. More complex traits that

0 commit comments

Comments
 (0)