1 // Copyright 2023 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef PARTITION_ALLOC_POINTERS_RAW_PTR_COUNTING_IMPL_FOR_TEST_H_
6 #define PARTITION_ALLOC_POINTERS_RAW_PTR_COUNTING_IMPL_FOR_TEST_H_
7 
8 #include <climits>
9 
10 #include "partition_alloc/pointers/raw_ptr.h"
11 #include "partition_alloc/pointers/raw_ptr_noop_impl.h"
12 
13 namespace base::test {
14 
15 // Provides a raw_ptr/raw_ref implementation that performs accounting for test
16 // purposes. It performs extra bookkeeping, e.g. to track the number of times
17 // the raw_ptr is wrapped, unrwapped, etc.
18 //
19 // Test only.
20 struct RawPtrCountingImplForTest : public base::internal::RawPtrNoOpImpl {
21   using SuperImpl = base::internal::RawPtrNoOpImpl;
22 
23   static constexpr bool kMustZeroOnConstruct = false;
24   static constexpr bool kMustZeroOnMove = false;
25   static constexpr bool kMustZeroOnDestruct = false;
26 
27   template <typename T>
WrapRawPtrRawPtrCountingImplForTest28   PA_ALWAYS_INLINE static constexpr T* WrapRawPtr(T* ptr) {
29     ++wrap_raw_ptr_cnt;
30     return SuperImpl::WrapRawPtr(ptr);
31   }
32 
33   template <typename T>
ReleaseWrappedPtrRawPtrCountingImplForTest34   PA_ALWAYS_INLINE static constexpr void ReleaseWrappedPtr(T* ptr) {
35     ++release_wrapped_ptr_cnt;
36     SuperImpl::ReleaseWrappedPtr(ptr);
37   }
38 
39   template <typename T>
SafelyUnwrapPtrForDereferenceRawPtrCountingImplForTest40   PA_ALWAYS_INLINE static constexpr T* SafelyUnwrapPtrForDereference(
41       T* wrapped_ptr) {
42     ++get_for_dereference_cnt;
43     return SuperImpl::SafelyUnwrapPtrForDereference(wrapped_ptr);
44   }
45 
46   template <typename T>
SafelyUnwrapPtrForExtractionRawPtrCountingImplForTest47   PA_ALWAYS_INLINE static constexpr T* SafelyUnwrapPtrForExtraction(
48       T* wrapped_ptr) {
49     ++get_for_extraction_cnt;
50     return SuperImpl::SafelyUnwrapPtrForExtraction(wrapped_ptr);
51   }
52 
53   template <typename T>
UnsafelyUnwrapPtrForComparisonRawPtrCountingImplForTest54   PA_ALWAYS_INLINE static constexpr T* UnsafelyUnwrapPtrForComparison(
55       T* wrapped_ptr) {
56     ++get_for_comparison_cnt;
57     return SuperImpl::UnsafelyUnwrapPtrForComparison(wrapped_ptr);
58   }
59 
IncrementSwapCountForTestRawPtrCountingImplForTest60   PA_ALWAYS_INLINE static void IncrementSwapCountForTest() {
61     ++wrapped_ptr_swap_cnt;
62     SuperImpl::IncrementSwapCountForTest();
63   }
64 
IncrementLessCountForTestRawPtrCountingImplForTest65   PA_ALWAYS_INLINE static void IncrementLessCountForTest() {
66     ++wrapped_ptr_less_cnt;
67     SuperImpl::IncrementLessCountForTest();
68   }
69 
70   template <typename T>
WrapRawPtrForDuplicationRawPtrCountingImplForTest71   PA_ALWAYS_INLINE static constexpr T* WrapRawPtrForDuplication(T* ptr) {
72     ++wrap_raw_ptr_for_dup_cnt;
73     return SuperImpl::WrapRawPtrForDuplication(ptr);
74   }
75 
76   template <typename T>
UnsafelyUnwrapPtrForDuplicationRawPtrCountingImplForTest77   PA_ALWAYS_INLINE static constexpr T* UnsafelyUnwrapPtrForDuplication(
78       T* wrapped_ptr) {
79     ++get_for_duplication_cnt;
80     return SuperImpl::UnsafelyUnwrapPtrForDuplication(wrapped_ptr);
81   }
82 
83   template <typename T>
TraceRawPtrCountingImplForTest84   static constexpr void Trace(uint64_t owner_id, T* wrapped_ptr) {
85     SuperImpl::Trace(owner_id, wrapped_ptr);
86   }
87 
UntraceRawPtrCountingImplForTest88   static constexpr void Untrace(uint64_t owner_id) {
89     SuperImpl::Untrace(owner_id);
90   }
91 
ClearCountersRawPtrCountingImplForTest92   static void ClearCounters() {
93     wrap_raw_ptr_cnt = 0;
94     release_wrapped_ptr_cnt = 0;
95     get_for_dereference_cnt = 0;
96     get_for_extraction_cnt = 0;
97     get_for_comparison_cnt = 0;
98     wrapped_ptr_swap_cnt = 0;
99     wrapped_ptr_less_cnt = 0;
100     pointer_to_member_operator_cnt = 0;
101     wrap_raw_ptr_for_dup_cnt = 0;
102     get_for_duplication_cnt = 0;
103   }
104 
105   static inline int wrap_raw_ptr_cnt = INT_MIN;
106   static inline int release_wrapped_ptr_cnt = INT_MIN;
107   static inline int get_for_dereference_cnt = INT_MIN;
108   static inline int get_for_extraction_cnt = INT_MIN;
109   static inline int get_for_comparison_cnt = INT_MIN;
110   static inline int wrapped_ptr_swap_cnt = INT_MIN;
111   static inline int wrapped_ptr_less_cnt = INT_MIN;
112   static inline int pointer_to_member_operator_cnt = INT_MIN;
113   static inline int wrap_raw_ptr_for_dup_cnt = INT_MIN;
114   static inline int get_for_duplication_cnt = INT_MIN;
115 };
116 
117 }  // namespace base::test
118 
119 #endif  // PARTITION_ALLOC_POINTERS_RAW_PTR_COUNTING_IMPL_FOR_TEST_H_
120