| 106 | } |
| 107 | |
| 108 | void HeapProfiler::record_alloc( |
| 109 | void* const p, const size_t size, const std::string& label) { |
| 110 | std::unique_lock<std::mutex> ul(mutex_); |
| 111 | |
| 112 | try { |
| 113 | const uint64_t addr = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(p)); |
| 114 | // Until we have replaced all dynamic memory APIs, we will silently |
| 115 | // ignore mismatched `record_alloc` and `record_dealloc` calls. |
| 116 | // assert(addr_to_alloc_.count(addr) == 0); |
| 117 | if (addr_to_alloc_.count(addr) > 0) { |
| 118 | // std::cerr << "TileDB:: duplicate alloc on " << std::hex << addr |
| 119 | // << std::endl; |
| 120 | return; |
| 121 | } |
| 122 | |
| 123 | // Increment the total number of allocation operations. |
| 124 | ++num_allocs_; |
| 125 | |
| 126 | // Record a mapping from `addr` to the bytes allocated and the user-provided |
| 127 | // string label (if provided). Note that labels are cached/deduped on |
| 128 | // `labels_cache_`. |
| 129 | addr_to_alloc_[addr] = std::make_pair(size, fetch_label_ptr(label)); |
| 130 | |
| 131 | // Increase the total number of allocated bytes. |
| 132 | num_alloc_bytes_ += size; |
| 133 | |
| 134 | // Perform an interval dump if necessary. |
| 135 | try_interval_dump(); |
| 136 | } catch (const std::bad_alloc&) { |
| 137 | dump_and_terminate_internal(); |
| 138 | } |
| 139 | } |
| 140 | |
| 141 | void HeapProfiler::record_dealloc(const void* const p) { |
| 142 | std::unique_lock<std::mutex> ul(mutex_); |
no test coverage detected