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// ===========================================================================
5// File: CallCounter.h
6//
7// ===========================================================================
8
9
10#ifndef CALL_COUNTER_H
11#define CALL_COUNTER_H
12
13#ifdef FEATURE_TIERED_COMPILATION
14
15// One entry in our dictionary mapping methods to the number of times they
16// have been invoked
17struct CallCounterEntry
18{
19 CallCounterEntry() {}
20 CallCounterEntry(const MethodDesc* m, const int c)
21 : pMethod(m), callCount(c) {}
22
23 const MethodDesc* pMethod;
24 int callCount;
25};
26
27class CallCounterHashTraits : public DefaultSHashTraits<CallCounterEntry>
28{
29public:
30 typedef typename DefaultSHashTraits<CallCounterEntry>::element_t element_t;
31 typedef typename DefaultSHashTraits<CallCounterEntry>::count_t count_t;
32
33 typedef const MethodDesc* key_t;
34
35 static key_t GetKey(element_t e)
36 {
37 LIMITED_METHOD_CONTRACT;
38 return e.pMethod;
39 }
40 static BOOL Equals(key_t k1, key_t k2)
41 {
42 LIMITED_METHOD_CONTRACT;
43 return k1 == k2;
44 }
45 static count_t Hash(key_t k)
46 {
47 LIMITED_METHOD_CONTRACT;
48 return (count_t)(size_t)k;
49 }
50
51 static const element_t Null() { LIMITED_METHOD_CONTRACT; return element_t(NULL, 0); }
52 static const element_t Deleted() { LIMITED_METHOD_CONTRACT; return element_t((const MethodDesc*)-1, 0); }
53 static bool IsNull(const element_t &e) { LIMITED_METHOD_CONTRACT; return e.pMethod == NULL; }
54 static bool IsDeleted(const element_t &e) { return e.pMethod == (const MethodDesc*)-1; }
55};
56
57typedef SHash<NoRemoveSHashTraits<CallCounterHashTraits>> CallCounterHash;
58
59
60// This is a per-appdomain cache of call counts for all code in that AppDomain.
61// Each method invocation should trigger a call to OnMethodCalled (until it is disabled per-method)
62// and the CallCounter will forward the call to the TieredCompilationManager including the
63// current call count.
64class CallCounter
65{
66public:
67#if defined(DACCESS_COMPILE) || defined(CROSSGEN_COMPILE)
68 CallCounter() {}
69#else
70 CallCounter();
71#endif
72
73 void OnMethodCalled(MethodDesc* pMethodDesc, TieredCompilationManager *pTieredCompilationManager, BOOL* shouldStopCountingCallsRef, BOOL* wasPromotedToTier1Ref);
74
75private:
76
77 // fields protected by lock
78 SpinLock m_lock;
79 CallCounterHash m_methodToCallCount;
80};
81
82#endif // FEATURE_TIERED_COMPILATION
83
84#endif // CALL_COUNTER_H
85