Skip to content

Commit f09ac25

Browse files
committed
style: clean up and add SAFETY comments
1 parent 99b406f commit f09ac25

File tree

3 files changed

+26
-28
lines changed

3 files changed

+26
-28
lines changed

profiling/src/profiling/stack_walking.rs

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ unsafe fn extract_file_and_line(execute_data: &zend_execute_data) -> (Option<Thi
8989
mod detail {
9090
use super::*;
9191
use crate::string_set::StringSet;
92-
use datadog_thin_str::ThinStr;
92+
use datadog_thin_str::{ThinHeader, ThinStr};
9393
use log::{debug, trace};
9494
use std::cell::RefCell;
9595
use std::ops::Deref;
@@ -103,34 +103,37 @@ mod detail {
103103
string_set: &'a mut StringSet,
104104
}
105105

106+
#[repr(usize)]
107+
enum CacheSlot {
108+
Function = 0,
109+
Filename = 1,
110+
}
111+
106112
impl<'a> StringCache<'a> {
107113
/// Makes a copy of the string in the cache slot. If there isn't a
108114
/// string in the slot currently, then create one by calling the
109115
/// provided function, store it in the string cache and cache slot,
110116
/// and return it.
111-
fn get_or_insert<F>(&mut self, slot: usize, f: F) -> Option<ThinString>
117+
fn get_or_insert<F>(&mut self, slot: CacheSlot, f: F) -> Option<ThinString>
112118
where
113119
F: FnOnce() -> Option<ThinString>,
114120
{
115-
debug_assert!(slot < self.cache_slots.len());
116-
let cached = unsafe { self.cache_slots.get_unchecked_mut(slot) };
121+
// SAFETY: the slot is in-bounds from CacheSlot -> usize conv.
122+
let cached = unsafe { self.cache_slots.get_unchecked_mut(slot as usize) };
117123

118-
let ptr = *cached as *mut u8;
124+
let ptr = *cached as *mut ThinHeader;
119125
match NonNull::new(ptr) {
120126
Some(non_null) => {
121-
// SAFETY: transmuting ThinStr from its repr.
122-
let thin_str: ThinStr = unsafe { core::mem::transmute(non_null) };
123127
// SAFETY: the string set is only reset between requests,
124-
// so this ThinStr points into the same string set that
125-
// created it.
126-
let str = unsafe { self.string_set.get_thin_str(thin_str) };
127-
Some(ThinString::from_str_in(str, Global))
128+
// so this ThinStr points into the same string set arena
129+
// that created it.
130+
let thin_str: ThinStr = unsafe { ThinStr::from_raw(non_null) };
131+
Some(ThinString::from_str_in(thin_str.deref(), Global))
128132
}
129133
None => {
130134
let string = f()?;
131135
let thin_str = self.string_set.insert(&string);
132-
// SAFETY: transmuting ThinStr into its repr.
133-
let non_null: NonNull<u8> = unsafe { core::mem::transmute(thin_str) };
136+
let non_null = thin_str.header_ptr();
134137
*cached = non_null.as_ptr() as usize;
135138
Some(string)
136139
}
@@ -321,15 +324,16 @@ mod detail {
321324
func: &zend_function,
322325
string_cache: &mut StringCache,
323326
) -> Option<ThinString> {
324-
let fname = string_cache.get_or_insert(0, || extract_function_name(func))?;
327+
let fname =
328+
string_cache.get_or_insert(CacheSlot::Function, || extract_function_name(func))?;
325329
Some(ThinString::from_str_in(&fname, Global))
326330
}
327331

328332
unsafe fn handle_file_cache_slot(
329333
execute_data: &zend_execute_data,
330334
string_cache: &mut StringCache,
331335
) -> (Option<ThinString>, u32) {
332-
let option = string_cache.get_or_insert(1, || -> Option<ThinString> {
336+
let option = string_cache.get_or_insert(CacheSlot::Filename, || -> Option<ThinString> {
333337
unsafe {
334338
// Safety: if we have cache slots, we definitely have a func.
335339
let func = &*execute_data.func;

profiling/src/string_set.rs

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use core::hash;
2-
use core::ops::Deref;
32
use datadog_alloc::{ChainAllocator, VirtualAllocator};
43
use datadog_thin_str::*;
54

@@ -103,16 +102,4 @@ impl StringSet {
103102
pub fn arena_used_bytes(&self) -> usize {
104103
self.arena.used_bytes()
105104
}
106-
107-
/// Creates a `&str` from the `thin_str`, binding it to the lifetime of
108-
/// the set.
109-
///
110-
/// # Safety
111-
/// The `thin_str` must live in this string set.
112-
#[inline]
113-
pub unsafe fn get_thin_str(&self, thin_str: ThinStr) -> &str {
114-
// todo: debug_assert it exists in the memory region?
115-
// SAFETY: see function's safety conditions.
116-
unsafe { core::mem::transmute(thin_str.deref()) }
117-
}
118105
}

thin-str/src/thin_str.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ impl ThinStr<'_> {
4848
// SAFETY: ConstStorage objects are valid Storage objects.
4949
unsafe { Self::from_raw(ptr) }
5050
}
51+
52+
/// Gets the header pointer for this string. Note that it is safe to get
53+
/// the pointer, but unsafe to do much with it other than to pass it back
54+
/// to [Self::from_raw].
55+
pub const fn header_ptr(&self) -> ptr::NonNull<ThinHeader> {
56+
self.ptr
57+
}
5158
}
5259

5360
impl From<usize> for ThinHeader {

0 commit comments

Comments
 (0)