summaryrefslogtreecommitdiffstats
path: root/vendor/icu_provider/src/datagen/heap_measure.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/icu_provider/src/datagen/heap_measure.rs')
-rw-r--r--vendor/icu_provider/src/datagen/heap_measure.rs59
1 files changed, 59 insertions, 0 deletions
diff --git a/vendor/icu_provider/src/datagen/heap_measure.rs b/vendor/icu_provider/src/datagen/heap_measure.rs
new file mode 100644
index 000000000..d451f3ebe
--- /dev/null
+++ b/vendor/icu_provider/src/datagen/heap_measure.rs
@@ -0,0 +1,59 @@
+// This file is part of ICU4X. For terms of use, please see the file
+// called LICENSE at the top level of the ICU4X source tree
+// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
+
+use crate::buf::{BufferFormat, BufferMarker};
+use crate::prelude::*;
+use yoke::trait_hack::YokeTraitHack;
+
+/// Stats on the heap size needed when attempting to zero-copy-deserialize
+/// a postcard-formatted data struct.
+#[derive(Debug, Copy, Clone, yoke::Yokeable, Default)]
+#[non_exhaustive]
+pub struct HeapStats {
+ /// Total bytes allocated during deserialization
+ pub total_bytes_allocated: u64,
+ /// Total bytes allocated during deserialization that have not yet been freed
+ pub net_bytes_allocated: usize,
+}
+
+/// The [`DataMarker`] marker type for [`HeapStats`].
+#[allow(clippy::exhaustive_structs)] // marker type
+pub struct HeapStatsMarker;
+
+impl DataMarker for HeapStatsMarker {
+ type Yokeable = HeapStats;
+}
+
+impl DataPayload<BufferMarker> {
+ /// Given a buffer known to be in postcard-0.7 format, attempt to zero-copy
+ /// deserialize it and record the amount of heap allocations that occurred.
+ ///
+ /// Ideally, this number should be zero.
+ ///
+ /// [`dhat`]'s profiler must be initialized before using this.
+ ///
+ /// # Panics
+ ///
+ /// Panics if the buffer is not in postcard-0.7 format.
+ #[allow(clippy::expect_used)] // The function documents when panics may occur.
+ pub fn attempt_zero_copy_heap_size<M>(self) -> HeapStats
+ where
+ M: DataMarker,
+ for<'a> &'a <M::Yokeable as yoke::Yokeable<'a>>::Output: serde::Serialize,
+ for<'de> YokeTraitHack<<M::Yokeable as yoke::Yokeable<'de>>::Output>:
+ serde::Deserialize<'de>,
+ {
+ let stats_before = dhat::HeapStats::get();
+ // reify, but do nothing with the type
+ let _reified_data: DataPayload<M> = self
+ .into_deserialized(BufferFormat::Postcard1)
+ .expect("Failed to deserialize BufferMarker as postcard-0.7");
+ let stats_after = dhat::HeapStats::get();
+
+ HeapStats {
+ total_bytes_allocated: stats_after.total_bytes - stats_before.total_bytes,
+ net_bytes_allocated: stats_after.curr_bytes - stats_before.curr_bytes,
+ }
+ }
+}