• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 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 #include "base/allocator/dispatcher/internal/dispatcher_internal.h"
6 
7 #include <iostream>
8 #include <tuple>
9 #include <utility>
10 
11 #include "base/allocator/dispatcher/subsystem.h"
12 #include "base/allocator/dispatcher/testing/dispatcher_test.h"
13 #include "base/allocator/dispatcher/testing/observer_mock.h"
14 #include "base/allocator/dispatcher/testing/tools.h"
15 #include "base/dcheck_is_on.h"
16 #include "partition_alloc/buildflags.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 
19 #if PA_BUILDFLAG(USE_PARTITION_ALLOC)
20 #include "partition_alloc/partition_alloc_allocation_data.h"
21 #endif
22 
23 using ::base::allocator::dispatcher::AllocationSubsystem;
24 using ::base::allocator::dispatcher::configuration::kMaximumNumberOfObservers;
25 using ::base::allocator::dispatcher::testing::CreateTupleOfPointers;
26 using ::base::allocator::dispatcher::testing::DispatcherTest;
27 using ::testing::_;
28 using ::testing::AllOf;
29 using ::testing::InSequence;
30 using ::testing::Matcher;
31 using ::testing::Property;
32 
33 namespace base::allocator::dispatcher::internal {
34 
35 namespace {
36 
AllocationNotificationMatches(Matcher<void * > address_matcher,Matcher<size_t> size_matcher,Matcher<AllocationSubsystem> subsystem_matcher=_)37 auto AllocationNotificationMatches(
38     Matcher<void*> address_matcher,
39     Matcher<size_t> size_matcher,
40     Matcher<AllocationSubsystem> subsystem_matcher = _) {
41   return AllOf(Property("address", &AllocationNotificationData::address,
42                         std::move(address_matcher)),
43                Property("size", &AllocationNotificationData::size,
44                         std::move(size_matcher)),
45                Property("allocation_subsystem",
46                         &AllocationNotificationData::allocation_subsystem,
47                         std::move(subsystem_matcher)));
48 }
49 
FreeNotificationMatches(Matcher<void * > address_matcher,Matcher<AllocationSubsystem> subsystem_matcher=_)50 auto FreeNotificationMatches(
51     Matcher<void*> address_matcher,
52     Matcher<AllocationSubsystem> subsystem_matcher = _) {
53   return AllOf(Property("address", &FreeNotificationData::address,
54                         std::move(address_matcher)),
55                Property("allocation_subsystem",
56                         &FreeNotificationData::allocation_subsystem,
57                         std::move(subsystem_matcher)));
58 }
59 
60 #if PA_BUILDFLAG(USE_PARTITION_ALLOC)
CreatePAAllocationData(void * address,size_t size,partition_alloc::TagViolationReportingMode mte_mode=partition_alloc::TagViolationReportingMode::kUndefined)61 ::partition_alloc::AllocationNotificationData CreatePAAllocationData(
62     void* address,
63     size_t size,
64     partition_alloc::TagViolationReportingMode mte_mode =
65         partition_alloc::TagViolationReportingMode::kUndefined) {
66   return ::partition_alloc::AllocationNotificationData(address, size, nullptr)
67 #if PA_BUILDFLAG(HAS_MEMORY_TAGGING)
68       .SetMteReportingMode(mte_mode)
69 #endif
70       ;
71 }
72 
CreatePAFreeData(void * address,partition_alloc::TagViolationReportingMode mte_mode=partition_alloc::TagViolationReportingMode::kUndefined)73 ::partition_alloc::FreeNotificationData CreatePAFreeData(
74     void* address,
75     partition_alloc::TagViolationReportingMode mte_mode =
76         partition_alloc::TagViolationReportingMode::kUndefined) {
77   return ::partition_alloc::FreeNotificationData(address)
78 #if PA_BUILDFLAG(HAS_MEMORY_TAGGING)
79       .SetMteReportingMode(mte_mode)
80 #endif
81       ;
82 }
83 #endif  // PA_BUILDFLAG(USE_PARTITION_ALLOC)
84 
85 struct AllocationEventDispatcherInternalTest : public DispatcherTest {
GetAllocatedAddressbase::allocator::dispatcher::internal::__anonb8b4cd1d0111::AllocationEventDispatcherInternalTest86   static void* GetAllocatedAddress() {
87     return reinterpret_cast<void*>(0x12345678);
88   }
GetAllocatedSizebase::allocator::dispatcher::internal::__anonb8b4cd1d0111::AllocationEventDispatcherInternalTest89   static unsigned int GetAllocatedSize() { return 35; }
GetEstimatedSizebase::allocator::dispatcher::internal::__anonb8b4cd1d0111::AllocationEventDispatcherInternalTest90   static unsigned int GetEstimatedSize() { return 77; }
GetFreedAddressbase::allocator::dispatcher::internal::__anonb8b4cd1d0111::AllocationEventDispatcherInternalTest91   static void* GetFreedAddress() {
92     return reinterpret_cast<void*>(0x876543210);
93   }
94 
95 #if PA_BUILDFLAG(USE_ALLOCATOR_SHIM)
GetNextAllocatorDispatchbase::allocator::dispatcher::internal::__anonb8b4cd1d0111::AllocationEventDispatcherInternalTest96   AllocatorDispatch* GetNextAllocatorDispatch() { return &allocator_dispatch_; }
alloc_functionbase::allocator::dispatcher::internal::__anonb8b4cd1d0111::AllocationEventDispatcherInternalTest97   static void* alloc_function(size_t, void*) { return GetAllocatedAddress(); }
alloc_unchecked_functionbase::allocator::dispatcher::internal::__anonb8b4cd1d0111::AllocationEventDispatcherInternalTest98   static void* alloc_unchecked_function(size_t, void*) {
99     return GetAllocatedAddress();
100   }
alloc_zero_initialized_functionbase::allocator::dispatcher::internal::__anonb8b4cd1d0111::AllocationEventDispatcherInternalTest101   static void* alloc_zero_initialized_function(size_t, size_t, void*) {
102     return GetAllocatedAddress();
103   }
alloc_aligned_functionbase::allocator::dispatcher::internal::__anonb8b4cd1d0111::AllocationEventDispatcherInternalTest104   static void* alloc_aligned_function(size_t, size_t, void*) {
105     return GetAllocatedAddress();
106   }
realloc_functionbase::allocator::dispatcher::internal::__anonb8b4cd1d0111::AllocationEventDispatcherInternalTest107   static void* realloc_function(void*, size_t, void*) {
108     return GetAllocatedAddress();
109   }
realloc_unchecked_functionbase::allocator::dispatcher::internal::__anonb8b4cd1d0111::AllocationEventDispatcherInternalTest110   static void* realloc_unchecked_function(void*, size_t, void*) {
111     return GetAllocatedAddress();
112   }
get_size_estimate_functionbase::allocator::dispatcher::internal::__anonb8b4cd1d0111::AllocationEventDispatcherInternalTest113   static size_t get_size_estimate_function(void*, void*) {
114     return GetEstimatedSize();
115   }
good_size_functionbase::allocator::dispatcher::internal::__anonb8b4cd1d0111::AllocationEventDispatcherInternalTest116   static size_t good_size_function(size_t size, void*) { return size; }
claimed_address_functionbase::allocator::dispatcher::internal::__anonb8b4cd1d0111::AllocationEventDispatcherInternalTest117   static bool claimed_address_function(void*, void*) {
118     return GetEstimatedSize();
119   }
batch_malloc_functionbase::allocator::dispatcher::internal::__anonb8b4cd1d0111::AllocationEventDispatcherInternalTest120   static unsigned batch_malloc_function(size_t,
121                                         void**,
122                                         unsigned num_requested,
123                                         void*) {
124     return num_requested;
125   }
aligned_malloc_functionbase::allocator::dispatcher::internal::__anonb8b4cd1d0111::AllocationEventDispatcherInternalTest126   static void* aligned_malloc_function(size_t, size_t, void*) {
127     return GetAllocatedAddress();
128   }
aligned_malloc_unchecked_functionbase::allocator::dispatcher::internal::__anonb8b4cd1d0111::AllocationEventDispatcherInternalTest129   static void* aligned_malloc_unchecked_function(size_t, size_t, void*) {
130     return GetAllocatedAddress();
131   }
aligned_realloc_functionbase::allocator::dispatcher::internal::__anonb8b4cd1d0111::AllocationEventDispatcherInternalTest132   static void* aligned_realloc_function(void*, size_t, size_t, void*) {
133     return GetAllocatedAddress();
134   }
aligned_realloc_unchecked_functionbase::allocator::dispatcher::internal::__anonb8b4cd1d0111::AllocationEventDispatcherInternalTest135   static void* aligned_realloc_unchecked_function(void*,
136                                                   size_t,
137                                                   size_t,
138                                                   void*) {
139     return GetAllocatedAddress();
140   }
141 
142   AllocatorDispatch allocator_dispatch_ = {&alloc_function,
143                                            &alloc_unchecked_function,
144                                            &alloc_zero_initialized_function,
145                                            &alloc_aligned_function,
146                                            &realloc_function,
147                                            &realloc_unchecked_function,
__anonb8b4cd1d0202base::allocator::dispatcher::internal::__anonb8b4cd1d0111::AllocationEventDispatcherInternalTest148                                            [](void*, void*) {},
149                                            &get_size_estimate_function,
150                                            &good_size_function,
151                                            &claimed_address_function,
152                                            &batch_malloc_function,
__anonb8b4cd1d0302base::allocator::dispatcher::internal::__anonb8b4cd1d0111::AllocationEventDispatcherInternalTest153                                            [](void**, unsigned, void*) {},
__anonb8b4cd1d0402base::allocator::dispatcher::internal::__anonb8b4cd1d0111::AllocationEventDispatcherInternalTest154                                            [](void*, size_t, void*) {},
__anonb8b4cd1d0502base::allocator::dispatcher::internal::__anonb8b4cd1d0111::AllocationEventDispatcherInternalTest155                                            [](void*, void*) {},
156                                            &aligned_malloc_function,
157                                            &aligned_malloc_unchecked_function,
158                                            &aligned_realloc_function,
159                                            &aligned_realloc_unchecked_function,
__anonb8b4cd1d0602base::allocator::dispatcher::internal::__anonb8b4cd1d0111::AllocationEventDispatcherInternalTest160                                            [](void*, void*) {}};
161 #endif
162 };
163 
164 }  // namespace
165 
166 using ::testing::NaggyMock;
167 using ::testing::StrictMock;
168 
169 using ObserverMock = StrictMock<testing::ObserverMock<>>;
170 
171 #if defined(GTEST_HAS_DEATH_TEST) && GTEST_HAS_DEATH_TEST && DCHECK_IS_ON()
TEST(AllocationEventDispatcherInternalDeathTest,VerifyDeathWhenObserverIsNull)172 TEST(AllocationEventDispatcherInternalDeathTest,
173      VerifyDeathWhenObserverIsNull) {
174   testing::ObserverMock<int> observer_1;
175   testing::ObserverMock<float> observer_2;
176   testing::ObserverMock<size_t>* null_observer = nullptr;
177   testing::ObserverMock<double> observer_3;
178 
179   const auto observer_ptrs =
180       std::make_tuple(&observer_1, &observer_2, null_observer, &observer_3);
181 
182   EXPECT_DEATH({ GetNotificationHooks(observer_ptrs); }, "");
183 }
184 #endif  // defined(GTEST_HAS_DEATH_TEST) && GTEST_HAS_DEATH_TEST &&
185         // DCHECK_IS_ON()
186 
187 #if PA_BUILDFLAG(USE_PARTITION_ALLOC)
TEST_F(AllocationEventDispatcherInternalTest,VerifyPartitionAllocatorHooksAreSet)188 TEST_F(AllocationEventDispatcherInternalTest,
189        VerifyPartitionAllocatorHooksAreSet) {
190   std::array<ObserverMock, 1> observers;
191 
192   const auto dispatch_data =
193       GetNotificationHooks(CreateTupleOfPointers(observers));
194 
195   EXPECT_NE(nullptr, dispatch_data.GetAllocationObserverHook());
196   EXPECT_NE(nullptr, dispatch_data.GetFreeObserverHook());
197 }
198 
TEST_F(AllocationEventDispatcherInternalTest,VerifyPartitionAllocatorHooksAreNullWhenNoObservers)199 TEST_F(AllocationEventDispatcherInternalTest,
200        VerifyPartitionAllocatorHooksAreNullWhenNoObservers) {
201   const auto dispatch_data = GetNotificationHooks(std::make_tuple());
202 
203   EXPECT_EQ(nullptr, dispatch_data.GetAllocationObserverHook());
204   EXPECT_EQ(nullptr, dispatch_data.GetFreeObserverHook());
205 }
206 
TEST_F(AllocationEventDispatcherInternalTest,VerifyPartitionAllocatorAllocationHooksTriggerCorrectly)207 TEST_F(AllocationEventDispatcherInternalTest,
208        VerifyPartitionAllocatorAllocationHooksTriggerCorrectly) {
209   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
210 
211   for (auto& mock : observers) {
212     EXPECT_CALL(mock, OnAllocation(_)).Times(0);
213     EXPECT_CALL(
214         mock, OnAllocation(AllocationNotificationMatches(this, sizeof(*this))))
215         .Times(1);
216     EXPECT_CALL(mock, OnFree(_)).Times(0);
217   }
218 
219   const auto dispatch_data =
220       GetNotificationHooks(CreateTupleOfPointers(observers));
221 
222   ::partition_alloc::AllocationNotificationData notification_data =
223       CreatePAAllocationData(this, sizeof(*this));
224 
225   dispatch_data.GetAllocationObserverHook()(notification_data);
226 }
227 
TEST_F(AllocationEventDispatcherInternalTest,VerifyPartitionAllocatorFreeHooksTriggerCorrectly)228 TEST_F(AllocationEventDispatcherInternalTest,
229        VerifyPartitionAllocatorFreeHooksTriggerCorrectly) {
230   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
231 
232   for (auto& mock : observers) {
233     EXPECT_CALL(mock, OnAllocation(_)).Times(0);
234     EXPECT_CALL(mock, OnFree(_)).Times(0);
235     EXPECT_CALL(mock, OnFree(FreeNotificationMatches(this))).Times(1);
236   }
237 
238   const auto dispatch_data =
239       GetNotificationHooks(CreateTupleOfPointers(observers));
240 
241   dispatch_data.GetFreeObserverHook()(CreatePAFreeData(this));
242 }
243 #endif  // PA_BUILDFLAG(USE_PARTITION_ALLOC)
244 
245 #if PA_BUILDFLAG(USE_ALLOCATOR_SHIM)
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimDataIsSet)246 TEST_F(AllocationEventDispatcherInternalTest, VerifyAllocatorShimDataIsSet) {
247   std::array<ObserverMock, 1> observers;
248 
249   const auto dispatch_data =
250       GetNotificationHooks(CreateTupleOfPointers(observers));
251   const auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
252   EXPECT_NE(nullptr, allocator_dispatch);
253   EXPECT_NE(nullptr, allocator_dispatch->alloc_function);
254   EXPECT_NE(nullptr, allocator_dispatch->alloc_unchecked_function);
255   EXPECT_NE(nullptr, allocator_dispatch->alloc_zero_initialized_function);
256   EXPECT_NE(nullptr, allocator_dispatch->alloc_aligned_function);
257   EXPECT_NE(nullptr, allocator_dispatch->realloc_function);
258   EXPECT_NE(nullptr, allocator_dispatch->realloc_unchecked_function);
259   EXPECT_NE(nullptr, allocator_dispatch->free_function);
260   EXPECT_NE(nullptr, allocator_dispatch->batch_malloc_function);
261   EXPECT_NE(nullptr, allocator_dispatch->batch_free_function);
262   EXPECT_NE(nullptr, allocator_dispatch->free_definite_size_function);
263   EXPECT_NE(nullptr, allocator_dispatch->try_free_default_function);
264   EXPECT_NE(nullptr, allocator_dispatch->aligned_malloc_function);
265   EXPECT_NE(nullptr, allocator_dispatch->aligned_malloc_unchecked_function);
266   EXPECT_NE(nullptr, allocator_dispatch->aligned_realloc_function);
267   EXPECT_NE(nullptr, allocator_dispatch->aligned_realloc_unchecked_function);
268   EXPECT_NE(nullptr, allocator_dispatch->aligned_free_function);
269 }
270 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimDataIsNullWhenNoObservers)271 TEST_F(AllocationEventDispatcherInternalTest,
272        VerifyAllocatorShimDataIsNullWhenNoObservers) {
273   const auto dispatch_data = GetNotificationHooks(std::make_tuple());
274 
275   EXPECT_EQ(nullptr, dispatch_data.GetAllocatorDispatch());
276 }
277 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_alloc_function)278 TEST_F(AllocationEventDispatcherInternalTest,
279        VerifyAllocatorShimHooksTriggerCorrectly_alloc_function) {
280   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
281 
282   for (auto& mock : observers) {
283     EXPECT_CALL(mock, OnAllocation(_)).Times(0);
284     EXPECT_CALL(mock, OnAllocation(AllocationNotificationMatches(
285                           GetAllocatedAddress(), GetAllocatedSize(),
286                           AllocationSubsystem::kAllocatorShim)))
287         .Times(1);
288     EXPECT_CALL(mock, OnFree(_)).Times(0);
289   }
290 
291   auto const dispatch_data =
292       GetNotificationHooks(CreateTupleOfPointers(observers));
293 
294   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
295   allocator_dispatch->next = GetNextAllocatorDispatch();
296 
297   auto* const allocated_address =
298       allocator_dispatch->alloc_function(GetAllocatedSize(), nullptr);
299 
300   EXPECT_EQ(allocated_address, GetAllocatedAddress());
301 }
302 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_alloc_unchecked_function)303 TEST_F(AllocationEventDispatcherInternalTest,
304        VerifyAllocatorShimHooksTriggerCorrectly_alloc_unchecked_function) {
305   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
306 
307   for (auto& mock : observers) {
308     EXPECT_CALL(mock, OnAllocation(_)).Times(0);
309     EXPECT_CALL(mock, OnAllocation(AllocationNotificationMatches(
310                           GetAllocatedAddress(), GetAllocatedSize(),
311                           AllocationSubsystem::kAllocatorShim)))
312         .Times(1);
313     EXPECT_CALL(mock, OnFree(_)).Times(0);
314   }
315 
316   auto const dispatch_data =
317       GetNotificationHooks(CreateTupleOfPointers(observers));
318 
319   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
320   allocator_dispatch->next = GetNextAllocatorDispatch();
321 
322   auto* const allocated_address =
323       allocator_dispatch->alloc_unchecked_function(GetAllocatedSize(), nullptr);
324 
325   EXPECT_EQ(allocated_address, GetAllocatedAddress());
326 }
327 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_alloc_zero_initialized_function)328 TEST_F(
329     AllocationEventDispatcherInternalTest,
330     VerifyAllocatorShimHooksTriggerCorrectly_alloc_zero_initialized_function) {
331   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
332   constexpr int n = 8;
333 
334   for (auto& mock : observers) {
335     EXPECT_CALL(mock, OnAllocation(_)).Times(0);
336     EXPECT_CALL(mock, OnAllocation(AllocationNotificationMatches(
337                           GetAllocatedAddress(), n * GetAllocatedSize(),
338                           AllocationSubsystem::kAllocatorShim)))
339         .Times(1);
340     EXPECT_CALL(mock, OnFree(_)).Times(0);
341   }
342 
343   auto const dispatch_data =
344       GetNotificationHooks(CreateTupleOfPointers(observers));
345 
346   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
347   allocator_dispatch->next = GetNextAllocatorDispatch();
348 
349   auto* const allocated_address =
350       allocator_dispatch->alloc_zero_initialized_function(n, GetAllocatedSize(),
351                                                           nullptr);
352 
353   EXPECT_EQ(allocated_address, GetAllocatedAddress());
354 }
355 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_alloc_aligned_function)356 TEST_F(AllocationEventDispatcherInternalTest,
357        VerifyAllocatorShimHooksTriggerCorrectly_alloc_aligned_function) {
358   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
359 
360   for (auto& mock : observers) {
361     EXPECT_CALL(mock, OnAllocation(_)).Times(0);
362     EXPECT_CALL(mock, OnAllocation(AllocationNotificationMatches(
363                           GetAllocatedAddress(), GetAllocatedSize(),
364                           AllocationSubsystem::kAllocatorShim)))
365         .Times(1);
366     EXPECT_CALL(mock, OnFree(_)).Times(0);
367   }
368 
369   auto const dispatch_data =
370       GetNotificationHooks(CreateTupleOfPointers(observers));
371 
372   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
373   allocator_dispatch->next = GetNextAllocatorDispatch();
374 
375   auto* const allocated_address = allocator_dispatch->alloc_aligned_function(
376       2048, GetAllocatedSize(), nullptr);
377 
378   EXPECT_EQ(allocated_address, GetAllocatedAddress());
379 }
380 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_realloc_function)381 TEST_F(AllocationEventDispatcherInternalTest,
382        VerifyAllocatorShimHooksTriggerCorrectly_realloc_function) {
383   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
384 
385   for (auto& mock : observers) {
386     InSequence execution_order;
387 
388     EXPECT_CALL(mock,
389                 OnFree(FreeNotificationMatches(
390                     GetFreedAddress(), AllocationSubsystem::kAllocatorShim)))
391         .Times(1);
392     EXPECT_CALL(mock, OnAllocation(AllocationNotificationMatches(
393                           GetAllocatedAddress(), GetAllocatedSize(),
394                           AllocationSubsystem::kAllocatorShim)))
395         .Times(1);
396   }
397 
398   auto const dispatch_data =
399       GetNotificationHooks(CreateTupleOfPointers(observers));
400 
401   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
402   allocator_dispatch->next = GetNextAllocatorDispatch();
403 
404   auto* const allocated_address = allocator_dispatch->realloc_function(
405       GetFreedAddress(), GetAllocatedSize(), nullptr);
406 
407   EXPECT_EQ(allocated_address, GetAllocatedAddress());
408 }
409 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_realloc_unchecked_function)410 TEST_F(AllocationEventDispatcherInternalTest,
411        VerifyAllocatorShimHooksTriggerCorrectly_realloc_unchecked_function) {
412   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
413 
414   for (auto& mock : observers) {
415     InSequence execution_order;
416 
417     EXPECT_CALL(mock,
418                 OnFree(FreeNotificationMatches(
419                     GetFreedAddress(), AllocationSubsystem::kAllocatorShim)))
420         .Times(1);
421     EXPECT_CALL(mock, OnAllocation(AllocationNotificationMatches(
422                           GetAllocatedAddress(), GetAllocatedSize(),
423                           AllocationSubsystem::kAllocatorShim)))
424         .Times(1);
425   }
426 
427   auto const dispatch_data =
428       GetNotificationHooks(CreateTupleOfPointers(observers));
429 
430   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
431   allocator_dispatch->next = GetNextAllocatorDispatch();
432 
433   auto* const allocated_address =
434       allocator_dispatch->realloc_unchecked_function(
435           GetFreedAddress(), GetAllocatedSize(), nullptr);
436 
437   EXPECT_EQ(allocated_address, GetAllocatedAddress());
438 }
439 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_free_function)440 TEST_F(AllocationEventDispatcherInternalTest,
441        VerifyAllocatorShimHooksTriggerCorrectly_free_function) {
442   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
443 
444   for (auto& mock : observers) {
445     EXPECT_CALL(mock,
446                 OnFree(FreeNotificationMatches(
447                     GetFreedAddress(), AllocationSubsystem::kAllocatorShim)))
448         .Times(1);
449     EXPECT_CALL(mock, OnAllocation(_)).Times(0);
450   }
451 
452   auto const dispatch_data =
453       GetNotificationHooks(CreateTupleOfPointers(observers));
454 
455   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
456   allocator_dispatch->next = GetNextAllocatorDispatch();
457 
458   allocator_dispatch->free_function(GetFreedAddress(), nullptr);
459 }
460 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_batch_malloc_function)461 TEST_F(AllocationEventDispatcherInternalTest,
462        VerifyAllocatorShimHooksTriggerCorrectly_batch_malloc_function) {
463   constexpr size_t allocation_batch_size = 10;
464   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
465   std::array<void*, allocation_batch_size> allocation_batch = {nullptr};
466 
467   for (auto& mock : observers) {
468     EXPECT_CALL(mock, OnFree(_)).Times(0);
469     EXPECT_CALL(mock, OnAllocation(AllocationNotificationMatches(
470                           nullptr, GetAllocatedSize(),
471                           AllocationSubsystem::kAllocatorShim)))
472         .Times(allocation_batch_size);
473   }
474 
475   auto const dispatch_data =
476       GetNotificationHooks(CreateTupleOfPointers(observers));
477 
478   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
479   EXPECT_NE(allocator_dispatch->batch_malloc_function, nullptr);
480 
481   allocator_dispatch->next = GetNextAllocatorDispatch();
482 
483   auto const number_allocated = allocator_dispatch->batch_malloc_function(
484       GetAllocatedSize(), allocation_batch.data(), allocation_batch_size,
485       nullptr);
486 
487   EXPECT_EQ(number_allocated, allocation_batch_size);
488 }
489 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_batch_free_function)490 TEST_F(AllocationEventDispatcherInternalTest,
491        VerifyAllocatorShimHooksTriggerCorrectly_batch_free_function) {
492   constexpr size_t allocation_batch_size = 10;
493   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
494   std::array<void*, allocation_batch_size> allocation_batch;
495   allocation_batch.fill(GetFreedAddress());
496 
497   for (auto& mock : observers) {
498     EXPECT_CALL(mock,
499                 OnFree(FreeNotificationMatches(
500                     GetFreedAddress(), AllocationSubsystem::kAllocatorShim)))
501         .Times(allocation_batch_size);
502     EXPECT_CALL(mock, OnAllocation(_)).Times(0);
503   }
504 
505   auto const dispatch_data =
506       GetNotificationHooks(CreateTupleOfPointers(observers));
507 
508   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
509   EXPECT_NE(allocator_dispatch->batch_free_function, nullptr);
510 
511   allocator_dispatch->next = GetNextAllocatorDispatch();
512 
513   allocator_dispatch->batch_free_function(allocation_batch.data(),
514                                           allocation_batch_size, nullptr);
515 }
516 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_free_definite_size_function)517 TEST_F(AllocationEventDispatcherInternalTest,
518        VerifyAllocatorShimHooksTriggerCorrectly_free_definite_size_function) {
519   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
520 
521   for (auto& mock : observers) {
522     EXPECT_CALL(
523         mock, OnFree(FreeNotificationMatches(
524                   GetAllocatedAddress(), AllocationSubsystem::kAllocatorShim)))
525         .Times(1);
526     EXPECT_CALL(mock, OnAllocation(_)).Times(0);
527   }
528 
529   DispatchData const dispatch_data =
530       GetNotificationHooks(CreateTupleOfPointers(observers));
531 
532   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
533   EXPECT_NE(allocator_dispatch->free_definite_size_function, nullptr);
534 
535   allocator_dispatch->next = GetNextAllocatorDispatch();
536 
537   allocator_dispatch->free_definite_size_function(GetAllocatedAddress(),
538                                                   GetAllocatedSize(), nullptr);
539 }
540 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_try_free_default_function)541 TEST_F(AllocationEventDispatcherInternalTest,
542        VerifyAllocatorShimHooksTriggerCorrectly_try_free_default_function) {
543   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
544 
545   for (auto& mock : observers) {
546     EXPECT_CALL(
547         mock, OnFree(FreeNotificationMatches(
548                   GetAllocatedAddress(), AllocationSubsystem::kAllocatorShim)))
549         .Times(1);
550     EXPECT_CALL(mock, OnAllocation(_)).Times(0);
551   }
552 
553   DispatchData const dispatch_data =
554       GetNotificationHooks(CreateTupleOfPointers(observers));
555 
556   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
557   EXPECT_NE(allocator_dispatch->try_free_default_function, nullptr);
558 
559   allocator_dispatch->next = GetNextAllocatorDispatch();
560 
561   allocator_dispatch->try_free_default_function(GetAllocatedAddress(), nullptr);
562 }
563 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_aligned_malloc_function)564 TEST_F(AllocationEventDispatcherInternalTest,
565        VerifyAllocatorShimHooksTriggerCorrectly_aligned_malloc_function) {
566   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
567 
568   for (auto& mock : observers) {
569     EXPECT_CALL(mock, OnAllocation(_)).Times(0);
570     EXPECT_CALL(mock, OnAllocation(AllocationNotificationMatches(
571                           GetAllocatedAddress(), GetAllocatedSize(),
572                           AllocationSubsystem::kAllocatorShim)))
573         .Times(1);
574     EXPECT_CALL(mock, OnFree(_)).Times(0);
575   }
576 
577   auto const dispatch_data =
578       GetNotificationHooks(CreateTupleOfPointers(observers));
579 
580   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
581   allocator_dispatch->next = GetNextAllocatorDispatch();
582 
583   auto* const allocated_address = allocator_dispatch->aligned_malloc_function(
584       GetAllocatedSize(), 2048, nullptr);
585 
586   EXPECT_EQ(allocated_address, GetAllocatedAddress());
587 }
588 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_aligned_malloc_unchecked_function)589 TEST_F(
590     AllocationEventDispatcherInternalTest,
591     VerifyAllocatorShimHooksTriggerCorrectly_aligned_malloc_unchecked_function) {
592   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
593 
594   for (auto& mock : observers) {
595     EXPECT_CALL(mock, OnAllocation(_)).Times(0);
596     EXPECT_CALL(mock, OnAllocation(AllocationNotificationMatches(
597                           GetAllocatedAddress(), GetAllocatedSize(),
598                           AllocationSubsystem::kAllocatorShim)))
599         .Times(1);
600     EXPECT_CALL(mock, OnFree(_)).Times(0);
601   }
602 
603   auto const dispatch_data =
604       GetNotificationHooks(CreateTupleOfPointers(observers));
605 
606   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
607   allocator_dispatch->next = GetNextAllocatorDispatch();
608 
609   auto* const allocated_address =
610       allocator_dispatch->aligned_malloc_unchecked_function(GetAllocatedSize(),
611                                                             2048, nullptr);
612 
613   EXPECT_EQ(allocated_address, GetAllocatedAddress());
614 }
615 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_aligned_realloc_function)616 TEST_F(AllocationEventDispatcherInternalTest,
617        VerifyAllocatorShimHooksTriggerCorrectly_aligned_realloc_function) {
618   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
619 
620   for (auto& mock : observers) {
621     InSequence execution_order;
622 
623     EXPECT_CALL(mock,
624                 OnFree(FreeNotificationMatches(
625                     GetFreedAddress(), AllocationSubsystem::kAllocatorShim)))
626         .Times(1);
627     EXPECT_CALL(mock, OnAllocation(AllocationNotificationMatches(
628                           GetAllocatedAddress(), GetAllocatedSize(),
629                           AllocationSubsystem::kAllocatorShim)))
630         .Times(1);
631   }
632 
633   auto const dispatch_data =
634       GetNotificationHooks(CreateTupleOfPointers(observers));
635 
636   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
637   allocator_dispatch->next = GetNextAllocatorDispatch();
638 
639   auto* const allocated_address = allocator_dispatch->aligned_realloc_function(
640       GetFreedAddress(), GetAllocatedSize(), 2048, nullptr);
641 
642   EXPECT_EQ(allocated_address, GetAllocatedAddress());
643 }
644 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_aligned_realloc_unchecked_function)645 TEST_F(
646     AllocationEventDispatcherInternalTest,
647     VerifyAllocatorShimHooksTriggerCorrectly_aligned_realloc_unchecked_function) {
648   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
649 
650   for (auto& mock : observers) {
651     InSequence execution_order;
652 
653     EXPECT_CALL(mock,
654                 OnFree(FreeNotificationMatches(
655                     GetFreedAddress(), AllocationSubsystem::kAllocatorShim)))
656         .Times(1);
657     EXPECT_CALL(mock, OnAllocation(AllocationNotificationMatches(
658                           GetAllocatedAddress(), GetAllocatedSize(),
659                           AllocationSubsystem::kAllocatorShim)))
660         .Times(1);
661   }
662 
663   auto const dispatch_data =
664       GetNotificationHooks(CreateTupleOfPointers(observers));
665 
666   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
667   allocator_dispatch->next = GetNextAllocatorDispatch();
668 
669   auto* const allocated_address =
670       allocator_dispatch->aligned_realloc_unchecked_function(
671           GetFreedAddress(), GetAllocatedSize(), 2048, nullptr);
672 
673   EXPECT_EQ(allocated_address, GetAllocatedAddress());
674 }
675 
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_aligned_free_function)676 TEST_F(AllocationEventDispatcherInternalTest,
677        VerifyAllocatorShimHooksTriggerCorrectly_aligned_free_function) {
678   std::array<ObserverMock, kMaximumNumberOfObservers> observers;
679 
680   for (auto& mock : observers) {
681     EXPECT_CALL(mock,
682                 OnFree(FreeNotificationMatches(
683                     GetFreedAddress(), AllocationSubsystem::kAllocatorShim)))
684         .Times(1);
685     EXPECT_CALL(mock, OnAllocation(_)).Times(0);
686   }
687 
688   auto const dispatch_data =
689       GetNotificationHooks(CreateTupleOfPointers(observers));
690 
691   auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
692   allocator_dispatch->next = GetNextAllocatorDispatch();
693 
694   allocator_dispatch->aligned_free_function(GetFreedAddress(), nullptr);
695 }
696 #endif  // PA_BUILDFLAG(USE_ALLOCATOR_SHIM)
697 }  // namespace base::allocator::dispatcher::internal
698