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 Andricvoid 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