• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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