1use alloc::boxed::Box;
2
3use crate::{rule_cache::RuleCache, unwind_rule::UnwindRule};
4
5pub use crate::rule_cache::CacheStats;
6
7pub trait AllocationPolicy {
10 type GimliUnwindContextStorage<R: gimli::ReaderOffset>: gimli::UnwindContextStorage<R>;
11 type GimliEvaluationStorage<R: gimli::Reader>: gimli::EvaluationStorage<R>;
12}
13
14pub struct MustNotAllocateDuringUnwind;
22
23#[doc(hidden)]
26pub struct StoreOnStack;
27
28impl<RO: gimli::ReaderOffset> gimli::UnwindContextStorage<RO> for StoreOnStack {
29 type Rules = [(gimli::Register, gimli::RegisterRule<RO>); 192];
30 type Stack = [gimli::UnwindTableRow<RO, Self>; 4];
31}
32
33impl<R: gimli::Reader> gimli::EvaluationStorage<R> for StoreOnStack {
34 type Stack = [gimli::Value; 64];
35 type ExpressionStack = [(R, R); 4];
36 type Result = [gimli::Piece<R>; 1];
37}
38
39impl AllocationPolicy for MustNotAllocateDuringUnwind {
40 type GimliUnwindContextStorage<R: gimli::ReaderOffset> = StoreOnStack;
41 type GimliEvaluationStorage<R: gimli::Reader> = StoreOnStack;
42}
43
44pub struct MayAllocateDuringUnwind;
50impl AllocationPolicy for MayAllocateDuringUnwind {
51 type GimliUnwindContextStorage<R: gimli::ReaderOffset> = gimli::StoreOnHeap;
52 type GimliEvaluationStorage<R: gimli::Reader> = gimli::StoreOnHeap;
53}
54
55pub struct Cache<R: UnwindRule, P: AllocationPolicy = MayAllocateDuringUnwind> {
63 pub(crate) gimli_unwind_context:
64 Box<gimli::UnwindContext<usize, P::GimliUnwindContextStorage<usize>>>,
65 pub(crate) rule_cache: RuleCache<R>,
66}
67
68impl<R: UnwindRule, P: AllocationPolicy> Cache<R, P> {
69 pub fn new() -> Self {
70 Self {
71 gimli_unwind_context: Box::new(gimli::UnwindContext::new_in()),
72 rule_cache: RuleCache::new(),
73 }
74 }
75}
76
77impl<R: UnwindRule, P: AllocationPolicy> Default for Cache<R, P> {
78 fn default() -> Self {
79 Self::new()
80 }
81}