Coverage Report

Created: 2024-05-16 12:16

/__w/smoldot/smoldot/repo/wasm-node/rust/src/allocator.rs
Line
Count
Source (jump to first uncovered line)
1
// Smoldot
2
// Copyright (C) 2019-2022  Parity Technologies (UK) Ltd.
3
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
4
5
// This program is free software: you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation, either version 3 of the License, or
8
// (at your option) any later version.
9
10
// This program is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
// GNU General Public License for more details.
14
15
// You should have received a copy of the GNU General Public License
16
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18
//! This module contains the `#[global_allocator]` used by the wasm node. This allocator is very
19
//! simple, apart from the fact that it counts the total number of bytes that have been allocated.
20
//! This value can then be retrieved by calling [`total_alloc_bytes`].
21
22
use core::{alloc, sync::atomic};
23
24
/// Returns the total number of bytes that have been allocated through the Rust `alloc` crate
25
/// throughout the entire Wasm node.
26
0
pub fn total_alloc_bytes() -> usize {
27
0
    ALLOCATOR.total.load(atomic::Ordering::Relaxed)
28
0
}
29
30
struct AllocCounter {
31
    /// Use the `dlmalloc` allocator. This is the library that the Rust standard library uses in
32
    /// the context of Wasm.
33
    /// See <https://github.com/rust-lang/rust/tree/1.47.0/library/std/src/sys/wasm>.
34
    inner: dlmalloc::GlobalDlmalloc,
35
36
    /// Total number of bytes allocated.
37
    total: atomic::AtomicUsize,
38
}
39
40
#[global_allocator]
41
298
static ALLOCATOR: AllocCounter = AllocCounter {
__rust_alloc
Line
Count
Source
41
148
static ALLOCATOR: AllocCounter = AllocCounter {
__rust_dealloc
Line
Count
Source
41
147
static ALLOCATOR: AllocCounter = AllocCounter {
__rust_realloc
Line
Count
Source
41
3
static ALLOCATOR: AllocCounter = AllocCounter {
Unexecuted instantiation: __rust_alloc_zeroed
42
    inner: dlmalloc::GlobalDlmalloc,
43
    total: atomic::AtomicUsize::new(0),
44
};
45
46
unsafe impl alloc::GlobalAlloc for AllocCounter {
47
148
    unsafe fn alloc(&self, layout: alloc::Layout) -> *mut u8 {
48
148
        let ret = self.inner.alloc(layout);
49
148
        if !ret.is_null() {
50
148
            self.total
51
148
                .fetch_add(layout.size(), atomic::Ordering::Relaxed);
52
148
        }
0
53
148
        ret
54
148
    }
55
56
147
    unsafe fn dealloc(&self, ptr: *mut u8, layout: alloc::Layout) {
57
147
        self.total
58
147
            .fetch_sub(layout.size(), atomic::Ordering::Relaxed);
59
147
        self.inner.dealloc(ptr, layout);
60
147
    }
61
62
0
    unsafe fn alloc_zeroed(&self, layout: alloc::Layout) -> *mut u8 {
63
0
        let ret = self.inner.alloc_zeroed(layout);
64
0
        if !ret.is_null() {
65
0
            self.total
66
0
                .fetch_add(layout.size(), atomic::Ordering::Relaxed);
67
0
        }
68
0
        ret
69
0
    }
70
71
3
    unsafe fn realloc(&self, ptr: *mut u8, layout: alloc::Layout, new_size: usize) -> *mut u8 {
72
3
        let ret = self.inner.realloc(ptr, layout, new_size);
73
3
        if !ret.is_null() {
74
3
            if new_size >= layout.size() {
75
3
                self.total
76
3
                    .fetch_add(new_size - layout.size(), atomic::Ordering::Relaxed);
77
3
            } else {
78
0
                self.total
79
0
                    .fetch_sub(layout.size() - new_size, atomic::Ordering::Relaxed);
80
0
            }
81
0
        }
82
3
        ret
83
3
    }
84
}