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 #include "base/allocator/dispatcher/testing/dispatcher_test.h"
7 #include "base/allocator/dispatcher/testing/observer_mock.h"
8 #include "base/allocator/dispatcher/testing/tools.h"
9 #include "base/allocator/partition_allocator/src/partition_alloc/partition_alloc_buildflags.h"
10 #include "base/dcheck_is_on.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12
13 #include <tuple>
14 #include <utility>
15
16 using ::base::allocator::dispatcher::configuration::kMaximumNumberOfObservers;
17 using ::base::allocator::dispatcher::testing::CreateTupleOfPointers;
18 using ::base::allocator::dispatcher::testing::DispatcherTest;
19 using ::testing::_;
20 using ::testing::InSequence;
21
22 namespace base::allocator::dispatcher::internal {
23
24 namespace {
25
26 struct AllocationEventDispatcherInternalTest : public DispatcherTest {
GetAllocatedAddressbase::allocator::dispatcher::internal::__anon7c20f1d10111::AllocationEventDispatcherInternalTest27 static void* GetAllocatedAddress() {
28 return reinterpret_cast<void*>(0x12345678);
29 }
GetAllocatedSizebase::allocator::dispatcher::internal::__anon7c20f1d10111::AllocationEventDispatcherInternalTest30 static unsigned int GetAllocatedSize() { return 35; }
GetEstimatedSizebase::allocator::dispatcher::internal::__anon7c20f1d10111::AllocationEventDispatcherInternalTest31 static unsigned int GetEstimatedSize() { return 77; }
GetFreedAddressbase::allocator::dispatcher::internal::__anon7c20f1d10111::AllocationEventDispatcherInternalTest32 static void* GetFreedAddress() {
33 return reinterpret_cast<void*>(0x876543210);
34 }
35
36 #if BUILDFLAG(USE_ALLOCATOR_SHIM)
GetNextAllocatorDispatchbase::allocator::dispatcher::internal::__anon7c20f1d10111::AllocationEventDispatcherInternalTest37 AllocatorDispatch* GetNextAllocatorDispatch() { return &allocator_dispatch_; }
alloc_functionbase::allocator::dispatcher::internal::__anon7c20f1d10111::AllocationEventDispatcherInternalTest38 static void* alloc_function(const AllocatorDispatch*, size_t, void*) {
39 return GetAllocatedAddress();
40 }
alloc_unchecked_functionbase::allocator::dispatcher::internal::__anon7c20f1d10111::AllocationEventDispatcherInternalTest41 static void* alloc_unchecked_function(const AllocatorDispatch*,
42 size_t,
43 void*) {
44 return GetAllocatedAddress();
45 }
alloc_zero_initialized_functionbase::allocator::dispatcher::internal::__anon7c20f1d10111::AllocationEventDispatcherInternalTest46 static void* alloc_zero_initialized_function(const AllocatorDispatch*,
47 size_t,
48 size_t,
49 void*) {
50 return GetAllocatedAddress();
51 }
alloc_aligned_functionbase::allocator::dispatcher::internal::__anon7c20f1d10111::AllocationEventDispatcherInternalTest52 static void* alloc_aligned_function(const AllocatorDispatch*,
53 size_t,
54 size_t,
55 void*) {
56 return GetAllocatedAddress();
57 }
realloc_functionbase::allocator::dispatcher::internal::__anon7c20f1d10111::AllocationEventDispatcherInternalTest58 static void* realloc_function(const AllocatorDispatch*,
59 void*,
60 size_t,
61 void*) {
62 return GetAllocatedAddress();
63 }
get_size_estimate_functionbase::allocator::dispatcher::internal::__anon7c20f1d10111::AllocationEventDispatcherInternalTest64 static size_t get_size_estimate_function(const AllocatorDispatch*,
65 void*,
66 void*) {
67 return GetEstimatedSize();
68 }
good_size_functionbase::allocator::dispatcher::internal::__anon7c20f1d10111::AllocationEventDispatcherInternalTest69 static size_t good_size_function(const AllocatorDispatch*,
70 size_t size,
71 void*) {
72 return size;
73 }
claimed_address_functionbase::allocator::dispatcher::internal::__anon7c20f1d10111::AllocationEventDispatcherInternalTest74 static bool claimed_address_function(const AllocatorDispatch*, void*, void*) {
75 return GetEstimatedSize();
76 }
batch_malloc_functionbase::allocator::dispatcher::internal::__anon7c20f1d10111::AllocationEventDispatcherInternalTest77 static unsigned batch_malloc_function(const AllocatorDispatch*,
78 size_t,
79 void**,
80 unsigned num_requested,
81 void*) {
82 return num_requested;
83 }
aligned_malloc_functionbase::allocator::dispatcher::internal::__anon7c20f1d10111::AllocationEventDispatcherInternalTest84 static void* aligned_malloc_function(const AllocatorDispatch*,
85 size_t,
86 size_t,
87 void*) {
88 return GetAllocatedAddress();
89 }
aligned_realloc_functionbase::allocator::dispatcher::internal::__anon7c20f1d10111::AllocationEventDispatcherInternalTest90 static void* aligned_realloc_function(const AllocatorDispatch*,
91 void*,
92 size_t,
93 size_t,
94 void*) {
95 return GetAllocatedAddress();
96 }
97
98 AllocatorDispatch allocator_dispatch_ = {
99 &alloc_function,
100 &alloc_unchecked_function,
101 &alloc_zero_initialized_function,
102 &alloc_aligned_function,
103 &realloc_function,
__anon7c20f1d10202base::allocator::dispatcher::internal::__anon7c20f1d10111::AllocationEventDispatcherInternalTest104 [](const AllocatorDispatch*, void*, void*) {},
105 &get_size_estimate_function,
106 &good_size_function,
107 &claimed_address_function,
108 &batch_malloc_function,
__anon7c20f1d10302base::allocator::dispatcher::internal::__anon7c20f1d10111::AllocationEventDispatcherInternalTest109 [](const AllocatorDispatch*, void**, unsigned, void*) {},
__anon7c20f1d10402base::allocator::dispatcher::internal::__anon7c20f1d10111::AllocationEventDispatcherInternalTest110 [](const AllocatorDispatch*, void*, size_t, void*) {},
__anon7c20f1d10502base::allocator::dispatcher::internal::__anon7c20f1d10111::AllocationEventDispatcherInternalTest111 [](const AllocatorDispatch*, void*, void*) {},
112 &aligned_malloc_function,
113 &aligned_realloc_function,
__anon7c20f1d10602base::allocator::dispatcher::internal::__anon7c20f1d10111::AllocationEventDispatcherInternalTest114 [](const AllocatorDispatch*, void*, void*) {}};
115 #endif
116 };
117
118 } // namespace
119
120 using ::testing::NaggyMock;
121 using ::testing::StrictMock;
122
123 using ObserverMock = StrictMock<testing::ObserverMock<>>;
124
125 #if defined(GTEST_HAS_DEATH_TEST) && GTEST_HAS_DEATH_TEST && DCHECK_IS_ON()
TEST(AllocationEventDispatcherInternalDeathTest,VerifyDeathWhenObserverIsNull)126 TEST(AllocationEventDispatcherInternalDeathTest,
127 VerifyDeathWhenObserverIsNull) {
128 testing::ObserverMock<int> observer_1;
129 testing::ObserverMock<float> observer_2;
130 testing::ObserverMock<size_t>* null_observer = nullptr;
131 testing::ObserverMock<double> observer_3;
132
133 const auto observer_ptrs =
134 std::make_tuple(&observer_1, &observer_2, null_observer, &observer_3);
135
136 EXPECT_DEATH({ GetNotificationHooks(observer_ptrs); }, "");
137 }
138 #endif // defined(GTEST_HAS_DEATH_TEST) && GTEST_HAS_DEATH_TEST &&
139 // DCHECK_IS_ON()
140
141 #if BUILDFLAG(USE_PARTITION_ALLOC)
TEST_F(AllocationEventDispatcherInternalTest,VerifyPartitionAllocatorHooksAreSet)142 TEST_F(AllocationEventDispatcherInternalTest,
143 VerifyPartitionAllocatorHooksAreSet) {
144 std::array<ObserverMock, 1> observers;
145
146 const auto dispatch_data =
147 GetNotificationHooks(CreateTupleOfPointers(observers));
148
149 EXPECT_NE(nullptr, dispatch_data.GetAllocationObserverHook());
150 EXPECT_NE(nullptr, dispatch_data.GetFreeObserverHook());
151 }
152
TEST_F(AllocationEventDispatcherInternalTest,VerifyPartitionAllocatorHooksAreNullWhenNoObservers)153 TEST_F(AllocationEventDispatcherInternalTest,
154 VerifyPartitionAllocatorHooksAreNullWhenNoObservers) {
155 const auto dispatch_data = GetNotificationHooks(std::make_tuple());
156
157 EXPECT_EQ(nullptr, dispatch_data.GetAllocationObserverHook());
158 EXPECT_EQ(nullptr, dispatch_data.GetFreeObserverHook());
159 }
160
TEST_F(AllocationEventDispatcherInternalTest,VerifyPartitionAllocatorAllocationHooksTriggerCorrectly)161 TEST_F(AllocationEventDispatcherInternalTest,
162 VerifyPartitionAllocatorAllocationHooksTriggerCorrectly) {
163 std::array<ObserverMock, kMaximumNumberOfObservers> observers;
164
165 for (auto& mock : observers) {
166 EXPECT_CALL(mock, OnAllocation(_, _, _, _)).Times(0);
167 EXPECT_CALL(mock, OnAllocation(this, sizeof(*this), _, _)).Times(1);
168 EXPECT_CALL(mock, OnFree(_)).Times(0);
169 }
170
171 const auto dispatch_data =
172 GetNotificationHooks(CreateTupleOfPointers(observers));
173
174 dispatch_data.GetAllocationObserverHook()(
175 partition_alloc::AllocationNotificationData(this, sizeof(*this),
176 nullptr));
177 }
178
TEST_F(AllocationEventDispatcherInternalTest,VerifyPartitionAllocatorFreeHooksTriggerCorrectly)179 TEST_F(AllocationEventDispatcherInternalTest,
180 VerifyPartitionAllocatorFreeHooksTriggerCorrectly) {
181 std::array<ObserverMock, kMaximumNumberOfObservers> observers;
182
183 for (auto& mock : observers) {
184 EXPECT_CALL(mock, OnAllocation(_, _, _, _)).Times(0);
185 EXPECT_CALL(mock, OnFree(_)).Times(0);
186 EXPECT_CALL(mock, OnFree(this)).Times(1);
187 }
188
189 const auto dispatch_data =
190 GetNotificationHooks(CreateTupleOfPointers(observers));
191
192 dispatch_data.GetFreeObserverHook()(
193 partition_alloc::FreeNotificationData(this));
194 }
195 #endif
196
197 #if BUILDFLAG(USE_ALLOCATOR_SHIM)
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimDataIsSet)198 TEST_F(AllocationEventDispatcherInternalTest, VerifyAllocatorShimDataIsSet) {
199 std::array<ObserverMock, 1> observers;
200
201 const auto dispatch_data =
202 GetNotificationHooks(CreateTupleOfPointers(observers));
203 const auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
204 EXPECT_NE(nullptr, allocator_dispatch);
205 EXPECT_NE(nullptr, allocator_dispatch->alloc_function);
206 EXPECT_NE(nullptr, allocator_dispatch->alloc_unchecked_function);
207 EXPECT_NE(nullptr, allocator_dispatch->alloc_zero_initialized_function);
208 EXPECT_NE(nullptr, allocator_dispatch->alloc_aligned_function);
209 EXPECT_NE(nullptr, allocator_dispatch->realloc_function);
210 EXPECT_NE(nullptr, allocator_dispatch->free_function);
211 EXPECT_NE(nullptr, allocator_dispatch->get_size_estimate_function);
212 EXPECT_NE(nullptr, allocator_dispatch->claimed_address_function);
213 EXPECT_NE(nullptr, allocator_dispatch->batch_malloc_function);
214 EXPECT_NE(nullptr, allocator_dispatch->batch_free_function);
215 EXPECT_NE(nullptr, allocator_dispatch->free_definite_size_function);
216 EXPECT_NE(nullptr, allocator_dispatch->try_free_default_function);
217 EXPECT_NE(nullptr, allocator_dispatch->aligned_malloc_function);
218 EXPECT_NE(nullptr, allocator_dispatch->aligned_realloc_function);
219 EXPECT_NE(nullptr, allocator_dispatch->aligned_free_function);
220 }
221
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimDataIsNullWhenNoObservers)222 TEST_F(AllocationEventDispatcherInternalTest,
223 VerifyAllocatorShimDataIsNullWhenNoObservers) {
224 const auto dispatch_data = GetNotificationHooks(std::make_tuple());
225
226 EXPECT_EQ(nullptr, dispatch_data.GetAllocatorDispatch());
227 }
228
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_alloc_function)229 TEST_F(AllocationEventDispatcherInternalTest,
230 VerifyAllocatorShimHooksTriggerCorrectly_alloc_function) {
231 std::array<ObserverMock, kMaximumNumberOfObservers> observers;
232
233 for (auto& mock : observers) {
234 EXPECT_CALL(mock, OnAllocation(_, _, _, _)).Times(0);
235 EXPECT_CALL(mock, OnAllocation(GetAllocatedAddress(), GetAllocatedSize(),
236 AllocationSubsystem::kAllocatorShim, _))
237 .Times(1);
238 EXPECT_CALL(mock, OnFree(_)).Times(0);
239 }
240
241 auto const dispatch_data =
242 GetNotificationHooks(CreateTupleOfPointers(observers));
243
244 auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
245 allocator_dispatch->next = GetNextAllocatorDispatch();
246
247 auto* const allocated_address = allocator_dispatch->alloc_function(
248 allocator_dispatch, GetAllocatedSize(), nullptr);
249
250 EXPECT_EQ(allocated_address, GetAllocatedAddress());
251 }
252
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_alloc_unchecked_function)253 TEST_F(AllocationEventDispatcherInternalTest,
254 VerifyAllocatorShimHooksTriggerCorrectly_alloc_unchecked_function) {
255 std::array<ObserverMock, kMaximumNumberOfObservers> observers;
256
257 for (auto& mock : observers) {
258 EXPECT_CALL(mock, OnAllocation(_, _, _, _)).Times(0);
259 EXPECT_CALL(mock, OnAllocation(GetAllocatedAddress(), GetAllocatedSize(),
260 AllocationSubsystem::kAllocatorShim, _))
261 .Times(1);
262 EXPECT_CALL(mock, OnFree(_)).Times(0);
263 }
264
265 auto const dispatch_data =
266 GetNotificationHooks(CreateTupleOfPointers(observers));
267
268 auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
269 allocator_dispatch->next = GetNextAllocatorDispatch();
270
271 auto* const allocated_address = allocator_dispatch->alloc_unchecked_function(
272 allocator_dispatch, GetAllocatedSize(), nullptr);
273
274 EXPECT_EQ(allocated_address, GetAllocatedAddress());
275 }
276
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_alloc_zero_initialized_function)277 TEST_F(
278 AllocationEventDispatcherInternalTest,
279 VerifyAllocatorShimHooksTriggerCorrectly_alloc_zero_initialized_function) {
280 std::array<ObserverMock, kMaximumNumberOfObservers> observers;
281 constexpr int n = 8;
282
283 for (auto& mock : observers) {
284 EXPECT_CALL(mock, OnAllocation(_, _, _, _)).Times(0);
285 EXPECT_CALL(mock,
286 OnAllocation(GetAllocatedAddress(), n * GetAllocatedSize(),
287 AllocationSubsystem::kAllocatorShim, _))
288 .Times(1);
289 EXPECT_CALL(mock, OnFree(_)).Times(0);
290 }
291
292 auto const dispatch_data =
293 GetNotificationHooks(CreateTupleOfPointers(observers));
294
295 auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
296 allocator_dispatch->next = GetNextAllocatorDispatch();
297
298 auto* const allocated_address =
299 allocator_dispatch->alloc_zero_initialized_function(
300 allocator_dispatch, n, GetAllocatedSize(), nullptr);
301
302 EXPECT_EQ(allocated_address, GetAllocatedAddress());
303 }
304
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_alloc_aligned_function)305 TEST_F(AllocationEventDispatcherInternalTest,
306 VerifyAllocatorShimHooksTriggerCorrectly_alloc_aligned_function) {
307 std::array<ObserverMock, kMaximumNumberOfObservers> observers;
308
309 for (auto& mock : observers) {
310 EXPECT_CALL(mock, OnAllocation(_, _, _, _)).Times(0);
311 EXPECT_CALL(mock, OnAllocation(GetAllocatedAddress(), GetAllocatedSize(),
312 AllocationSubsystem::kAllocatorShim, _))
313 .Times(1);
314 EXPECT_CALL(mock, OnFree(_)).Times(0);
315 }
316
317 auto const dispatch_data =
318 GetNotificationHooks(CreateTupleOfPointers(observers));
319
320 auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
321 allocator_dispatch->next = GetNextAllocatorDispatch();
322
323 auto* const allocated_address = allocator_dispatch->alloc_aligned_function(
324 allocator_dispatch, 2048, GetAllocatedSize(), nullptr);
325
326 EXPECT_EQ(allocated_address, GetAllocatedAddress());
327 }
328
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_realloc_function)329 TEST_F(AllocationEventDispatcherInternalTest,
330 VerifyAllocatorShimHooksTriggerCorrectly_realloc_function) {
331 std::array<ObserverMock, kMaximumNumberOfObservers> observers;
332
333 for (auto& mock : observers) {
334 InSequence execution_order;
335
336 EXPECT_CALL(mock, OnFree(GetFreedAddress())).Times(1);
337 EXPECT_CALL(mock, OnAllocation(GetAllocatedAddress(), GetAllocatedSize(),
338 AllocationSubsystem::kAllocatorShim, _))
339 .Times(1);
340 }
341
342 auto const dispatch_data =
343 GetNotificationHooks(CreateTupleOfPointers(observers));
344
345 auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
346 allocator_dispatch->next = GetNextAllocatorDispatch();
347
348 auto* const allocated_address = allocator_dispatch->realloc_function(
349 allocator_dispatch, GetFreedAddress(), GetAllocatedSize(), nullptr);
350
351 EXPECT_EQ(allocated_address, GetAllocatedAddress());
352 }
353
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_free_function)354 TEST_F(AllocationEventDispatcherInternalTest,
355 VerifyAllocatorShimHooksTriggerCorrectly_free_function) {
356 std::array<ObserverMock, kMaximumNumberOfObservers> observers;
357
358 for (auto& mock : observers) {
359 EXPECT_CALL(mock, OnFree(GetFreedAddress())).Times(1);
360 EXPECT_CALL(mock, OnAllocation(_, _, _, _)).Times(0);
361 }
362
363 auto const dispatch_data =
364 GetNotificationHooks(CreateTupleOfPointers(observers));
365
366 auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
367 allocator_dispatch->next = GetNextAllocatorDispatch();
368
369 allocator_dispatch->free_function(allocator_dispatch, GetFreedAddress(),
370 nullptr);
371 }
372
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_get_size_estimate_function)373 TEST_F(AllocationEventDispatcherInternalTest,
374 VerifyAllocatorShimHooksTriggerCorrectly_get_size_estimate_function) {
375 std::array<ObserverMock, kMaximumNumberOfObservers> observers;
376
377 for (auto& mock : observers) {
378 EXPECT_CALL(mock, OnFree(_)).Times(0);
379 EXPECT_CALL(mock, OnAllocation(_, _, _, _)).Times(0);
380 }
381
382 auto const dispatch_data =
383 GetNotificationHooks(CreateTupleOfPointers(observers));
384
385 auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
386 allocator_dispatch->next = GetNextAllocatorDispatch();
387
388 auto const estimated_size = allocator_dispatch->get_size_estimate_function(
389 allocator_dispatch, GetAllocatedAddress(), nullptr);
390
391 EXPECT_EQ(estimated_size, GetEstimatedSize());
392 }
393
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_batch_malloc_function)394 TEST_F(AllocationEventDispatcherInternalTest,
395 VerifyAllocatorShimHooksTriggerCorrectly_batch_malloc_function) {
396 constexpr size_t allocation_batch_size = 10;
397 std::array<ObserverMock, kMaximumNumberOfObservers> observers;
398 std::array<void*, allocation_batch_size> allocation_batch = {nullptr};
399
400 for (auto& mock : observers) {
401 EXPECT_CALL(mock, OnFree(_)).Times(0);
402 EXPECT_CALL(mock, OnAllocation(nullptr, GetAllocatedSize(),
403 AllocationSubsystem::kAllocatorShim, _))
404 .Times(allocation_batch_size);
405 }
406
407 auto const dispatch_data =
408 GetNotificationHooks(CreateTupleOfPointers(observers));
409
410 auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
411 EXPECT_NE(allocator_dispatch->batch_malloc_function, nullptr);
412
413 allocator_dispatch->next = GetNextAllocatorDispatch();
414
415 auto const number_allocated = allocator_dispatch->batch_malloc_function(
416 allocator_dispatch, GetAllocatedSize(), allocation_batch.data(),
417 allocation_batch_size, nullptr);
418
419 EXPECT_EQ(number_allocated, allocation_batch_size);
420 }
421
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_batch_free_function)422 TEST_F(AllocationEventDispatcherInternalTest,
423 VerifyAllocatorShimHooksTriggerCorrectly_batch_free_function) {
424 constexpr size_t allocation_batch_size = 10;
425 std::array<ObserverMock, kMaximumNumberOfObservers> observers;
426 std::array<void*, allocation_batch_size> allocation_batch;
427 allocation_batch.fill(GetFreedAddress());
428
429 for (auto& mock : observers) {
430 EXPECT_CALL(mock, OnFree(GetFreedAddress())).Times(allocation_batch_size);
431 EXPECT_CALL(mock, OnAllocation(_, _, _, _)).Times(0);
432 }
433
434 auto const dispatch_data =
435 GetNotificationHooks(CreateTupleOfPointers(observers));
436
437 auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
438 EXPECT_NE(allocator_dispatch->batch_free_function, nullptr);
439
440 allocator_dispatch->next = GetNextAllocatorDispatch();
441
442 allocator_dispatch->batch_free_function(allocator_dispatch,
443 allocation_batch.data(),
444 allocation_batch_size, nullptr);
445 }
446
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_free_definite_size_function)447 TEST_F(AllocationEventDispatcherInternalTest,
448 VerifyAllocatorShimHooksTriggerCorrectly_free_definite_size_function) {
449 std::array<ObserverMock, kMaximumNumberOfObservers> observers;
450
451 for (auto& mock : observers) {
452 EXPECT_CALL(mock, OnFree(GetAllocatedAddress())).Times(1);
453 EXPECT_CALL(mock, OnAllocation(_, _, _, _)).Times(0);
454 }
455
456 DispatchData const dispatch_data =
457 GetNotificationHooks(CreateTupleOfPointers(observers));
458
459 auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
460 EXPECT_NE(allocator_dispatch->free_definite_size_function, nullptr);
461
462 allocator_dispatch->next = GetNextAllocatorDispatch();
463
464 allocator_dispatch->free_definite_size_function(
465 allocator_dispatch, GetAllocatedAddress(), GetAllocatedSize(), nullptr);
466 }
467
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_try_free_default_function)468 TEST_F(AllocationEventDispatcherInternalTest,
469 VerifyAllocatorShimHooksTriggerCorrectly_try_free_default_function) {
470 std::array<ObserverMock, kMaximumNumberOfObservers> observers;
471
472 for (auto& mock : observers) {
473 EXPECT_CALL(mock, OnFree(GetAllocatedAddress())).Times(1);
474 EXPECT_CALL(mock, OnAllocation(_, _, _, _)).Times(0);
475 }
476
477 DispatchData const dispatch_data =
478 GetNotificationHooks(CreateTupleOfPointers(observers));
479
480 auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
481 EXPECT_NE(allocator_dispatch->try_free_default_function, nullptr);
482
483 allocator_dispatch->next = GetNextAllocatorDispatch();
484
485 allocator_dispatch->try_free_default_function(allocator_dispatch,
486 GetAllocatedAddress(), nullptr);
487 }
488
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_aligned_malloc_function)489 TEST_F(AllocationEventDispatcherInternalTest,
490 VerifyAllocatorShimHooksTriggerCorrectly_aligned_malloc_function) {
491 std::array<ObserverMock, kMaximumNumberOfObservers> observers;
492
493 for (auto& mock : observers) {
494 EXPECT_CALL(mock, OnAllocation(_, _, _, _)).Times(0);
495 EXPECT_CALL(mock, OnAllocation(GetAllocatedAddress(), GetAllocatedSize(),
496 AllocationSubsystem::kAllocatorShim, _))
497 .Times(1);
498 EXPECT_CALL(mock, OnFree(_)).Times(0);
499 }
500
501 auto const dispatch_data =
502 GetNotificationHooks(CreateTupleOfPointers(observers));
503
504 auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
505 allocator_dispatch->next = GetNextAllocatorDispatch();
506
507 auto* const allocated_address = allocator_dispatch->aligned_malloc_function(
508 allocator_dispatch, GetAllocatedSize(), 2048, nullptr);
509
510 EXPECT_EQ(allocated_address, GetAllocatedAddress());
511 }
512
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_aligned_realloc_function)513 TEST_F(AllocationEventDispatcherInternalTest,
514 VerifyAllocatorShimHooksTriggerCorrectly_aligned_realloc_function) {
515 std::array<ObserverMock, kMaximumNumberOfObservers> observers;
516
517 for (auto& mock : observers) {
518 InSequence execution_order;
519
520 EXPECT_CALL(mock, OnFree(GetFreedAddress())).Times(1);
521 EXPECT_CALL(mock, OnAllocation(GetAllocatedAddress(), GetAllocatedSize(),
522 AllocationSubsystem::kAllocatorShim, _))
523 .Times(1);
524 }
525
526 auto const dispatch_data =
527 GetNotificationHooks(CreateTupleOfPointers(observers));
528
529 auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
530 allocator_dispatch->next = GetNextAllocatorDispatch();
531
532 auto* const allocated_address = allocator_dispatch->aligned_realloc_function(
533 allocator_dispatch, GetFreedAddress(), GetAllocatedSize(), 2048, nullptr);
534
535 EXPECT_EQ(allocated_address, GetAllocatedAddress());
536 }
537
TEST_F(AllocationEventDispatcherInternalTest,VerifyAllocatorShimHooksTriggerCorrectly_aligned_free_function)538 TEST_F(AllocationEventDispatcherInternalTest,
539 VerifyAllocatorShimHooksTriggerCorrectly_aligned_free_function) {
540 std::array<ObserverMock, kMaximumNumberOfObservers> observers;
541
542 for (auto& mock : observers) {
543 EXPECT_CALL(mock, OnFree(GetFreedAddress())).Times(1);
544 EXPECT_CALL(mock, OnAllocation(_, _, _, _)).Times(0);
545 }
546
547 auto const dispatch_data =
548 GetNotificationHooks(CreateTupleOfPointers(observers));
549
550 auto* const allocator_dispatch = dispatch_data.GetAllocatorDispatch();
551 allocator_dispatch->next = GetNextAllocatorDispatch();
552
553 allocator_dispatch->aligned_free_function(allocator_dispatch,
554 GetFreedAddress(), nullptr);
555 }
556
557 #endif
558 } // namespace base::allocator::dispatcher::internal
559