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 #include "base/debug/allocation_trace.h"
6
7 #include <array>
8 #include <atomic>
9
10 #include "base/check_op.h"
11
12 namespace base::debug::tracer {
13
IsRecording() const14 bool OperationRecord::IsRecording() const {
15 if (is_recording_.test_and_set()) {
16 return true;
17 }
18
19 is_recording_.clear();
20 return false;
21 }
22
GetOperationType() const23 OperationType OperationRecord::GetOperationType() const {
24 return operation_type_;
25 }
26
GetAddress() const27 const void* OperationRecord::GetAddress() const {
28 return address_;
29 }
30
GetSize() const31 size_t OperationRecord::GetSize() const {
32 return size_;
33 }
34
GetStackTrace() const35 const StackTraceContainer& OperationRecord::GetStackTrace() const {
36 return stack_trace_;
37 }
38
OnAllocation(const void * allocated_address,size_t allocated_size,base::allocator::dispatcher::AllocationSubsystem subsystem,const char * type)39 void AllocationTraceRecorder::OnAllocation(
40 const void* allocated_address,
41 size_t allocated_size,
42 base::allocator::dispatcher::AllocationSubsystem subsystem,
43 const char* type) {
44 for (auto idx = GetNextIndex();
45 !alloc_trace_buffer_[idx].InitializeAllocation(allocated_address,
46 allocated_size);
47 idx = GetNextIndex()) {
48 }
49 }
50
OnFree(const void * freed_address)51 void AllocationTraceRecorder::OnFree(const void* freed_address) {
52 for (auto idx = GetNextIndex();
53 !alloc_trace_buffer_[idx].InitializeFree(freed_address);
54 idx = GetNextIndex()) {
55 }
56 }
57
IsValid() const58 bool AllocationTraceRecorder::IsValid() const {
59 return kMemoryGuard == prologue_ && kMemoryGuard == epilogue_;
60 }
61
size() const62 size_t AllocationTraceRecorder::size() const {
63 return std::min(kMaximumNumberOfMemoryOperationTraces,
64 total_number_of_records_.load(std::memory_order_relaxed));
65 }
66
operator [](size_t idx) const67 const OperationRecord& AllocationTraceRecorder::operator[](size_t idx) const {
68 DCHECK_LT(idx, size());
69
70 const size_t array_index =
71 size() < GetMaximumNumberOfTraces()
72 ? idx
73 : WrapIdxIfNeeded(
74 total_number_of_records_.load(std::memory_order_relaxed) + idx);
75
76 DCHECK_LT(array_index, alloc_trace_buffer_.size());
77
78 return alloc_trace_buffer_[array_index];
79 }
80
81 } // namespace base::debug::tracer