Welcome to mirror list, hosted at ThFree Co, Russian Federation.

genanalysis.cpp « vm « coreclr « src - github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 65f37375c33c34ba48b6414e0985300246d8b6fa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#include "common.h"
#include "genanalysis.h"
#include "eventpipeadapter.h"

GcGenAnalysisState gcGenAnalysisState = GcGenAnalysisState::Uninitialized;
EventPipeSession* gcGenAnalysisEventPipeSession = nullptr;
uint64_t gcGenAnalysisEventPipeSessionId = (uint64_t)-1;
GcGenAnalysisState gcGenAnalysisConfigured = GcGenAnalysisState::Uninitialized;
int64_t gcGenAnalysisGen = -1;
int64_t gcGenAnalysisBytes = 0;
int64_t gcGenAnalysisIndex = 0;
uint32_t gcGenAnalysisBufferMB = 0;
bool gcGenAnalysisTrace = true;
bool gcGenAnalysisDump = false;

/* static */ void GenAnalysis::Initialize()
{
#ifndef GEN_ANALYSIS_STRESS
    if (gcGenAnalysisConfigured == GcGenAnalysisState::Uninitialized)
    {
        bool match = true;
        CLRConfigStringHolder gcGenAnalysisCmd(CLRConfig::GetConfigValue(CLRConfig::INTERNAL_GCGenAnalysisCmd));
        if (gcGenAnalysisCmd != nullptr)
        {
            // Get the managed command line.
            LPCWSTR pCmdLine = GetCommandLineForDiagnostics();
            match = wcsncmp(pCmdLine, gcGenAnalysisCmd, wcslen(gcGenAnalysisCmd)) == 0;
        }
        if (match && !CLRConfig::IsConfigOptionSpecified(W("GCGenAnalysisGen")))
        {
            match = false;
        }
        if (match && !CLRConfig::IsConfigOptionSpecified(W("GCGenAnalysisBytes")))
        {
            match = false;
        }
        if (match)
        {
            gcGenAnalysisBytes = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_GCGenAnalysisBytes);
            gcGenAnalysisGen = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_GCGenAnalysisGen);
            gcGenAnalysisIndex = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_GCGenAnalysisIndex);
            gcGenAnalysisBufferMB = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_EventPipeCircularMB);
            gcGenAnalysisTrace = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_GCGenAnalysisTrace);
            gcGenAnalysisDump = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_GCGenAnalysisDump);
            gcGenAnalysisConfigured = GcGenAnalysisState::Enabled;
        }
        else
        {
            gcGenAnalysisConfigured = GcGenAnalysisState::Disabled;
        }
    }
    if ((gcGenAnalysisConfigured == GcGenAnalysisState::Enabled) && (gcGenAnalysisState == GcGenAnalysisState::Uninitialized))
#endif
    {
        if (gcGenAnalysisTrace)
        {
            EnableGenerationalAwareSession();
        }
        if (gcGenAnalysisDump)
        {
            gcGenAnalysisState = GcGenAnalysisState::Enabled;
        }
    }
}

/* static */ void GenAnalysis::EnableGenerationalAwareSession()
{
    LPCWSTR outputPath = nullptr;
    outputPath = GENAWARE_TRACE_FILE_NAME;
    NewArrayHolder<COR_PRF_EVENTPIPE_PROVIDER_CONFIG> pProviders;
    int providerCnt = 1;
    pProviders = new COR_PRF_EVENTPIPE_PROVIDER_CONFIG[providerCnt];
    const uint64_t GCHeapAndTypeNamesKeyword        = 0x00001000000; // This keyword is necessary for the type names
    const uint64_t GCHeapSurvivalAndMovementKeyword = 0x00000400000; // This keyword is necessary for the generation range data.
    const uint64_t GCHeapDumpKeyword                = 0x00000100000; // This keyword is necessary for enabling walking the heap
    const uint64_t TypeKeyword                      = 0x00000080000; // This keyword is necessary for enabling BulkType events
    const uint64_t keyword                          = GCHeapAndTypeNamesKeyword|GCHeapSurvivalAndMovementKeyword|GCHeapDumpKeyword|TypeKeyword;
    pProviders[0].providerName = W("Microsoft-Windows-DotNETRuntime");
    pProviders[0].keywords = keyword;
    pProviders[0].loggingLevel = (uint32_t)EP_EVENT_LEVEL_VERBOSE;
    pProviders[0].filterData = nullptr;

    EventPipeProviderConfigurationAdapter configAdapter(pProviders, providerCnt);
    gcGenAnalysisEventPipeSessionId = EventPipeAdapter::Enable(
        outputPath,
        gcGenAnalysisBufferMB,
        configAdapter,
        EP_SESSION_TYPE_FILE,
        EP_SERIALIZATION_FORMAT_NETTRACE_V4,
        false,
        nullptr,
        nullptr,
        nullptr
    );
    if (gcGenAnalysisEventPipeSessionId > 0)
    {
        gcGenAnalysisEventPipeSession= EventPipeAdapter::GetSession(gcGenAnalysisEventPipeSessionId);
        EventPipeAdapter::PauseSession(gcGenAnalysisEventPipeSession);
        EventPipeAdapter::StartStreaming(gcGenAnalysisEventPipeSessionId);
        gcGenAnalysisState = GcGenAnalysisState::Enabled;
    }
}