From: Konstantin Baladurin Date: Wed, 14 Feb 2018 07:46:19 +0000 (+0300) Subject: Historam: doesn't allocate additional memory to store counts X-Git-Tag: submit/tizen/20210909.063632~11030^2~5659^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=561cffae9989148fb77823c5d1e228346624217d;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Historam: doesn't allocate additional memory to store counts It allows to remove deallocation in destuctor that can lead to uaf for static Historgam's objects during shutdown. Commit migrated from https://github.com/dotnet/coreclr/commit/a14840ebeb1f7a76b8d957eb39f63eef0250a872 --- diff --git a/src/coreclr/src/jit/compiler.cpp b/src/coreclr/src/jit/compiler.cpp index c53dd86..ce9b3dc 100644 --- a/src/coreclr/src/jit/compiler.cpp +++ b/src/coreclr/src/jit/compiler.cpp @@ -276,18 +276,18 @@ NodeSizeStats genNodeSizeStats; NodeSizeStats genNodeSizeStatsPerFunc; unsigned genTreeNcntHistBuckets[] = {10, 20, 30, 40, 50, 100, 200, 300, 400, 500, 1000, 5000, 10000, 0}; -Histogram genTreeNcntHist(HostAllocator::getHostAllocator(), genTreeNcntHistBuckets); +Histogram genTreeNcntHist(genTreeNcntHistBuckets); unsigned genTreeNsizHistBuckets[] = {1000, 5000, 10000, 50000, 100000, 500000, 1000000, 0}; -Histogram genTreeNsizHist(HostAllocator::getHostAllocator(), genTreeNsizHistBuckets); +Histogram genTreeNsizHist(genTreeNsizHistBuckets); #endif // MEASURE_NODE_SIZE /*****************************************************************************/ #if MEASURE_MEM_ALLOC unsigned memSizeHistBuckets[] = {20, 50, 75, 100, 150, 250, 500, 1000, 5000, 0}; -Histogram memAllocHist(HostAllocator::getHostAllocator(), memSizeHistBuckets); -Histogram memUsedHist(HostAllocator::getHostAllocator(), memSizeHistBuckets); +Histogram memAllocHist(memSizeHistBuckets); +Histogram memUsedHist(memSizeHistBuckets); #endif // MEASURE_MEM_ALLOC @@ -339,16 +339,16 @@ unsigned argTotalGTF_ASGinArgs; unsigned argMaxTempsPerMethod; unsigned argCntBuckets[] = {0, 1, 2, 3, 4, 5, 6, 10, 0}; -Histogram argCntTable(HostAllocator::getHostAllocator(), argCntBuckets); +Histogram argCntTable(argCntBuckets); unsigned argDWordCntBuckets[] = {0, 1, 2, 3, 4, 5, 6, 10, 0}; -Histogram argDWordCntTable(HostAllocator::getHostAllocator(), argDWordCntBuckets); +Histogram argDWordCntTable(argDWordCntBuckets); unsigned argDWordLngCntBuckets[] = {0, 1, 2, 3, 4, 5, 6, 10, 0}; -Histogram argDWordLngCntTable(HostAllocator::getHostAllocator(), argDWordLngCntBuckets); +Histogram argDWordLngCntTable(argDWordLngCntBuckets); unsigned argTempsCntBuckets[] = {0, 1, 2, 3, 4, 5, 6, 10, 0}; -Histogram argTempsCntTable(HostAllocator::getHostAllocator(), argTempsCntBuckets); +Histogram argTempsCntTable(argTempsCntBuckets); #endif // CALL_ARG_STATS @@ -375,12 +375,12 @@ Histogram argTempsCntTable(HostAllocator::getHostAllocator(), argTempsCntBuckets // -------------------------------------------------- unsigned bbCntBuckets[] = {1, 2, 3, 5, 10, 20, 50, 100, 1000, 10000, 0}; -Histogram bbCntTable(HostAllocator::getHostAllocator(), bbCntBuckets); +Histogram bbCntTable(bbCntBuckets); /* Histogram for the IL opcode size of methods with a single basic block */ unsigned bbSizeBuckets[] = {1, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 0}; -Histogram bbOneBBSizeTable(HostAllocator::getHostAllocator(), bbSizeBuckets); +Histogram bbOneBBSizeTable(bbSizeBuckets); #endif // COUNT_BASIC_BLOCKS @@ -411,12 +411,12 @@ bool loopOverflowThisMethod; // True if we exceeded the max # of loops in t /* Histogram for number of loops in a method */ unsigned loopCountBuckets[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0}; -Histogram loopCountTable(HostAllocator::getHostAllocator(), loopCountBuckets); +Histogram loopCountTable(loopCountBuckets); /* Histogram for number of loop exits */ unsigned loopExitCountBuckets[] = {0, 1, 2, 3, 4, 5, 6, 0}; -Histogram loopExitCountTable(HostAllocator::getHostAllocator(), loopExitCountBuckets); +Histogram loopExitCountTable(loopExitCountBuckets); #endif // COUNT_LOOPS diff --git a/src/coreclr/src/jit/emit.cpp b/src/coreclr/src/jit/emit.cpp index 9f42aea..5c70e08 100644 --- a/src/coreclr/src/jit/emit.cpp +++ b/src/coreclr/src/jit/emit.cpp @@ -257,13 +257,13 @@ static unsigned totActualSize; unsigned emitter::emitIFcounts[emitter::IF_COUNT]; static unsigned emitSizeBuckets[] = {100, 1024 * 1, 1024 * 2, 1024 * 3, 1024 * 4, 1024 * 5, 1024 * 10, 0}; -static Histogram emitSizeTable(HostAllocator::getHostAllocator(), emitSizeBuckets); +static Histogram emitSizeTable(emitSizeBuckets); static unsigned GCrefsBuckets[] = {0, 1, 2, 5, 10, 20, 50, 128, 256, 512, 1024, 0}; -static Histogram GCrefsTable(HostAllocator::getHostAllocator(), GCrefsBuckets); +static Histogram GCrefsTable(GCrefsBuckets); static unsigned stkDepthBuckets[] = {0, 1, 2, 5, 10, 16, 32, 128, 1024, 0}; -static Histogram stkDepthTable(HostAllocator::getHostAllocator(), stkDepthBuckets); +static Histogram stkDepthTable(stkDepthBuckets); size_t emitter::emitSizeMethod; diff --git a/src/coreclr/src/jit/jit.h b/src/coreclr/src/jit/jit.h index 00f5cb2..82970706c 100644 --- a/src/coreclr/src/jit/jit.h +++ b/src/coreclr/src/jit/jit.h @@ -695,11 +695,12 @@ inline size_t unsigned_abs(ssize_t x) #if CALL_ARG_STATS || COUNT_BASIC_BLOCKS || COUNT_LOOPS || EMITTER_STATS || MEASURE_NODE_SIZE || MEASURE_MEM_ALLOC +#define HISTOGRAM_MAX_SIZE_COUNT 64 + class Histogram { public: - Histogram(HostAllocator* allocator, const unsigned* const sizeTable); - ~Histogram(); + Histogram(const unsigned* const sizeTable); void dump(FILE* output); void record(unsigned size); @@ -707,10 +708,9 @@ public: private: void ensureAllocated(); - HostAllocator* m_allocator; unsigned m_sizeCount; const unsigned* const m_sizeTable; - unsigned* m_counts; + unsigned m_counts[HISTOGRAM_MAX_SIZE_COUNT]; }; #endif // CALL_ARG_STATS || COUNT_BASIC_BLOCKS || COUNT_LOOPS || EMITTER_STATS || MEASURE_NODE_SIZE diff --git a/src/coreclr/src/jit/utils.cpp b/src/coreclr/src/jit/utils.cpp index fda0d67..46d704c 100644 --- a/src/coreclr/src/jit/utils.cpp +++ b/src/coreclr/src/jit/utils.cpp @@ -882,8 +882,7 @@ void ConfigMethodRange::InitRanges(const wchar_t* rangeStr, unsigned capacity) * Histogram class. */ -Histogram::Histogram(HostAllocator* allocator, const unsigned* const sizeTable) - : m_allocator(allocator), m_sizeTable(sizeTable), m_counts(nullptr) +Histogram::Histogram(const unsigned* const sizeTable) : m_sizeTable(sizeTable) { unsigned sizeCount = 0; do @@ -891,32 +890,15 @@ Histogram::Histogram(HostAllocator* allocator, const unsigned* const sizeTable) sizeCount++; } while ((sizeTable[sizeCount] != 0) && (sizeCount < 1000)); - m_sizeCount = sizeCount; -} + assert(sizeCount < HISTOGRAM_MAX_SIZE_COUNT - 1); -Histogram::~Histogram() -{ - if (m_counts != nullptr) - { - m_allocator->Free(m_counts); - } -} + m_sizeCount = sizeCount; -// We need to lazy allocate the histogram data so static `Histogram` variables don't try to -// call the host memory allocator in the loader lock, which doesn't work. -void Histogram::ensureAllocated() -{ - if (m_counts == nullptr) - { - m_counts = new (m_allocator) unsigned[m_sizeCount + 1]; - memset(m_counts, 0, (m_sizeCount + 1) * sizeof(*m_counts)); - } + memset(m_counts, 0, (m_sizeCount + 1) * sizeof(*m_counts)); } void Histogram::dump(FILE* output) { - ensureAllocated(); - unsigned t = 0; for (unsigned i = 0; i < m_sizeCount; i++) { @@ -956,8 +938,6 @@ void Histogram::dump(FILE* output) void Histogram::record(unsigned size) { - ensureAllocated(); - unsigned i; for (i = 0; i < m_sizeCount; i++) {