1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 // ===========================================================================
7 // ===========================================================================
10 #ifndef CALL_COUNTER_H
11 #define CALL_COUNTER_H
13 #ifdef FEATURE_TIERED_COMPILATION
15 // One entry in our dictionary mapping methods to the number of times they
17 struct CallCounterEntry
20 CallCounterEntry(PTR_MethodDesc m, const int callCountLimit)
21 : pMethod(m), callCountLimit(callCountLimit) {}
23 PTR_MethodDesc pMethod;
26 #ifndef DACCESS_COMPILE
27 static CallCounterEntry CreateWithCallCountingDisabled(MethodDesc *m);
30 bool IsCallCountingEnabled() const
32 LIMITED_METHOD_CONTRACT;
33 return callCountLimit != INT_MAX;
36 #ifndef DACCESS_COMPILE
37 void DisableCallCounting()
39 LIMITED_METHOD_CONTRACT;
40 callCountLimit = INT_MAX;
45 typedef DPTR(struct CallCounterEntry) PTR_CallCounterEntry;
47 class CallCounterHashTraits : public DefaultSHashTraits<CallCounterEntry>
50 typedef typename DefaultSHashTraits<CallCounterEntry>::element_t element_t;
51 typedef typename DefaultSHashTraits<CallCounterEntry>::count_t count_t;
53 typedef PTR_MethodDesc key_t;
55 static key_t GetKey(element_t e)
57 LIMITED_METHOD_CONTRACT;
60 static BOOL Equals(key_t k1, key_t k2)
62 LIMITED_METHOD_CONTRACT;
65 static count_t Hash(key_t k)
67 LIMITED_METHOD_CONTRACT;
68 return (count_t)dac_cast<TADDR>(k);
71 static const element_t Null() { LIMITED_METHOD_CONTRACT; return element_t(PTR_NULL, 0); }
72 static const element_t Deleted() { LIMITED_METHOD_CONTRACT; return element_t((PTR_MethodDesc)-1, 0); }
73 static bool IsNull(const element_t &e) { LIMITED_METHOD_CONTRACT; return e.pMethod == PTR_NULL; }
74 static bool IsDeleted(const element_t &e) { return e.pMethod == (PTR_MethodDesc)-1; }
77 typedef SHash<NoRemoveSHashTraits<CallCounterHashTraits>> CallCounterHash;
80 // This is a per-appdomain cache of call counts for all code in that AppDomain.
81 // Each method invocation should trigger a call to OnMethodCalled (until it is disabled per-method)
82 // and the CallCounter will forward the call to the TieredCompilationManager including the
83 // current call count.
87 #ifdef DACCESS_COMPILE
93 static bool IsEligibleForCallCounting(PTR_MethodDesc pMethodDesc);
94 bool IsCallCountingEnabled(PTR_MethodDesc pMethodDesc);
95 #ifndef DACCESS_COMPILE
96 void DisableCallCounting(MethodDesc* pMethodDesc);
97 bool WasCalledAtMostOnce(MethodDesc* pMethodDesc);
100 void OnMethodCalled(MethodDesc* pMethodDesc, TieredCompilationManager *pTieredCompilationManager, BOOL* shouldStopCountingCallsRef, BOOL* wasPromotedToNextTierRef);
104 // fields protected by lock
106 CallCounterHash m_methodToCallCount;
109 #endif // FEATURE_TIERED_COMPILATION
111 #endif // CALL_COUNTER_H