xref: /freebsd/contrib/llvm-project/compiler-rt/lib/memprof/memprof_mibmap.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1349cc55cSDimitry Andric //===-- memprof_mibmap.cpp -----------------------------------------------===//
2349cc55cSDimitry Andric //
3349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6349cc55cSDimitry Andric //
7349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
8349cc55cSDimitry Andric //
9349cc55cSDimitry Andric // This file is a part of MemProfiler, a memory profiler.
10349cc55cSDimitry Andric //
11349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
12349cc55cSDimitry Andric 
13349cc55cSDimitry Andric #include "memprof_mibmap.h"
141fd87a68SDimitry Andric #include "profile/MemProfData.inc"
15349cc55cSDimitry Andric #include "sanitizer_common/sanitizer_allocator_internal.h"
16349cc55cSDimitry Andric #include "sanitizer_common/sanitizer_mutex.h"
17349cc55cSDimitry Andric 
18349cc55cSDimitry Andric namespace __memprof {
191fd87a68SDimitry Andric using ::llvm::memprof::MemInfoBlock;
20349cc55cSDimitry Andric 
InsertOrMerge(const uptr Id,const MemInfoBlock & Block,MIBMapTy & Map)21349cc55cSDimitry Andric void InsertOrMerge(const uptr Id, const MemInfoBlock &Block, MIBMapTy &Map) {
22349cc55cSDimitry Andric   MIBMapTy::Handle h(&Map, static_cast<uptr>(Id), /*remove=*/false,
23349cc55cSDimitry Andric                      /*create=*/true);
24349cc55cSDimitry Andric   if (h.created()) {
25349cc55cSDimitry Andric     LockedMemInfoBlock *lmib =
26349cc55cSDimitry Andric         (LockedMemInfoBlock *)InternalAlloc(sizeof(LockedMemInfoBlock));
27349cc55cSDimitry Andric     lmib->mutex.Init();
28349cc55cSDimitry Andric     lmib->mib = Block;
29349cc55cSDimitry Andric     *h = lmib;
30349cc55cSDimitry Andric   } else {
31349cc55cSDimitry Andric     LockedMemInfoBlock *lmib = *h;
32349cc55cSDimitry Andric     SpinMutexLock lock(&lmib->mutex);
33*0fca6ea1SDimitry Andric     uintptr_t ShorterHistogram;
34*0fca6ea1SDimitry Andric     if (Block.AccessHistogramSize > lmib->mib.AccessHistogramSize)
35*0fca6ea1SDimitry Andric       ShorterHistogram = lmib->mib.AccessHistogram;
36*0fca6ea1SDimitry Andric     else
37*0fca6ea1SDimitry Andric       ShorterHistogram = Block.AccessHistogram;
38*0fca6ea1SDimitry Andric 
39349cc55cSDimitry Andric     lmib->mib.Merge(Block);
40*0fca6ea1SDimitry Andric     // The larger histogram is kept and the shorter histogram is discarded after
41*0fca6ea1SDimitry Andric     // adding the counters to the larger historam. Free only the shorter
42*0fca6ea1SDimitry Andric     // Histogram
43*0fca6ea1SDimitry Andric     if (Block.AccessHistogramSize > 0 || lmib->mib.AccessHistogramSize > 0)
44*0fca6ea1SDimitry Andric       InternalFree((void *)ShorterHistogram);
45349cc55cSDimitry Andric   }
46349cc55cSDimitry Andric }
47349cc55cSDimitry Andric 
48349cc55cSDimitry Andric } // namespace __memprof
49