PerfCounterSet.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #pragma once
  6. #ifdef PERF_COUNTERS
  7. namespace PerfCounter
  8. {
  9. template <typename TCounter>
  10. class DefaultCounterSetInstance : public InstanceBase
  11. {
  12. public:
  13. DefaultCounterSetInstance() : InstanceBase(TCounter::GetProvider(), TCounter::GetGuid())
  14. {
  15. if (Initialize())
  16. {
  17. data = defaultData;
  18. }
  19. else
  20. {
  21. // if for any reason perf counter failed to initialize, try to create
  22. // shared memory instead. This will happen for sure if running under
  23. // Win8 AppContainer because they don't support v2 perf counters.
  24. // See comments in WWAHostJSCounterProvider for details.
  25. data = __super::InitializeSharedMemory(TCounter::MaxCounter, handle);
  26. if (data == nullptr)
  27. {
  28. data = defaultData;
  29. }
  30. }
  31. for (uint i = 0; i < TCounter::MaxCounter; i++)
  32. {
  33. data[i] = 0;
  34. counters[i].Initialize(*this, i, &data[i]);
  35. }
  36. }
  37. ~DefaultCounterSetInstance()
  38. {
  39. for (uint i = 0; i < TCounter::MaxCounter; i++)
  40. {
  41. counters[i].Uninitialize(*this, i);
  42. }
  43. if (data != defaultData)
  44. {
  45. __super::UninitializeSharedMemory(data, handle);
  46. }
  47. }
  48. Counter& GetCounter(uint id) { Assert(id < TCounter::MaxCounter); return counters[id]; }
  49. bool Initialize()
  50. {
  51. if (IsProviderInitialized())
  52. {
  53. char16 wszModuleName[_MAX_PATH];
  54. if (!PlatformAgnostic::SystemInfo::GetBinaryLocation(wszModuleName, _MAX_PATH))
  55. {
  56. return false;
  57. }
  58. char16 wszFilename[_MAX_FNAME];
  59. _wsplitpath_s(wszModuleName, NULL, 0, NULL, 0, wszFilename, _MAX_FNAME, NULL, 0);
  60. return __super::Initialize(wszFilename, GetCurrentProcessId());
  61. }
  62. return false;
  63. }
  64. private:
  65. DWORD defaultData[TCounter::MaxCounter];
  66. DWORD * data;
  67. HANDLE handle;
  68. Counter counters[TCounter::MaxCounter];
  69. };
  70. class PageAllocatorCounterSet
  71. {
  72. public:
  73. static Counter& GetReservedSizeCounter(PageAllocatorType type)
  74. { return instance.GetCounter(PageAllocatorCounterSetDefinition::GetReservedCounterId(type)); }
  75. static Counter& GetTotalReservedSizeCounter();
  76. static Counter& GetCommittedSizeCounter(PageAllocatorType type)
  77. { return instance.GetCounter(PageAllocatorCounterSetDefinition::GetCommittedCounterId(type)); }
  78. static Counter& GetTotalCommittedSizeCounter();
  79. static Counter& GetUsedSizeCounter(PageAllocatorType type)
  80. { return instance.GetCounter(PageAllocatorCounterSetDefinition::GetUsedCounterId(type)); }
  81. static Counter& GetTotalUsedSizeCounter();
  82. private:
  83. static DefaultCounterSetInstance<PageAllocatorCounterSetDefinition> instance;
  84. };
  85. class BasicCounterSet
  86. {
  87. public:
  88. static Counter& GetThreadContextCounter() { return instance.GetCounter(0); }
  89. static Counter& GetScriptContextCounter() { return instance.GetCounter(1); }
  90. static Counter& GetScriptContextActiveCounter() { return instance.GetCounter(2); }
  91. static Counter& GetScriptCodeBufferCountCounter() { return instance.GetCounter(3); }
  92. private:
  93. static DefaultCounterSetInstance<BasicCounterSetDefinition> instance;
  94. };
  95. class CodeCounterSet
  96. {
  97. public:
  98. static Counter& GetTotalByteCodeSizeCounter() { return instance.GetCounter(0); }
  99. static Counter& GetTotalNativeCodeSizeCounter() { return instance.GetCounter(1); }
  100. static Counter& GetTotalNativeCodeDataSizeCounter() { return instance.GetCounter(2); }
  101. static Counter& GetStaticByteCodeSizeCounter() { return instance.GetCounter(3); }
  102. static Counter& GetStaticNativeCodeSizeCounter() { return instance.GetCounter(4); }
  103. static Counter& GetStaticNativeCodeDataSizeCounter() { return instance.GetCounter(5); }
  104. static Counter& GetDynamicByteCodeSizeCounter() { return instance.GetCounter(6); }
  105. static Counter& GetDynamicNativeCodeSizeCounter() { return instance.GetCounter(7); }
  106. static Counter& GetDynamicNativeCodeDataSizeCounter() { return instance.GetCounter(8); }
  107. static Counter& GetTotalFunctionCounter() { return instance.GetCounter(9); }
  108. static Counter& GetStaticFunctionCounter() { return instance.GetCounter(10); }
  109. static Counter& GetDynamicFunctionCounter() { return instance.GetCounter(11); }
  110. static Counter& GetLoopNativeCodeSizeCounter() { return instance.GetCounter(12); }
  111. static Counter& GetFunctionNativeCodeSizeCounter() { return instance.GetCounter(13); }
  112. static Counter& GetDeferDeserializeFunctionProxyCounter() { return instance.GetCounter(14); }
  113. static Counter& GetDeserializedFunctionBodyCounter() { return instance.GetCounter(15); }
  114. static Counter& GetDeferredFunctionCounter() { return instance.GetCounter(16); }
  115. private:
  116. static DefaultCounterSetInstance<CodeCounterSetDefinition> instance;
  117. };
  118. #ifdef HEAP_PERF_COUNTERS
  119. class HeapCounterSet
  120. {
  121. public:
  122. static Counter& GetLiveObjectCounter() { return instance.GetCounter(0); }
  123. static Counter& GetLiveObjectSizeCounter() { return instance.GetCounter(1); }
  124. private:
  125. static DefaultCounterSetInstance<HeapCounterSetDefinition> instance;
  126. };
  127. #endif
  128. #ifdef RECYCLER_PERF_COUNTERS
  129. class RecyclerCounterSet
  130. {
  131. public:
  132. static Counter& GetLiveObjectSizeCounter() { return instance.GetCounter(0); }
  133. static Counter& GetLiveObjectCounter() { return instance.GetCounter(1); }
  134. static Counter& GetFreeObjectSizeCounter() { return instance.GetCounter(2); }
  135. static Counter& GetPinnedObjectCounter() { return instance.GetCounter(3); }
  136. static Counter& GetBindReferenceCounter() { return instance.GetCounter(4); }
  137. static Counter& GetPropertyRecordBindReferenceCounter() { return instance.GetCounter(5); }
  138. static Counter& GetLargeHeapBlockLiveObjectSizeCounter() { return instance.GetCounter(6); }
  139. static Counter& GetLargeHeapBlockLiveObjectCounter() { return instance.GetCounter(7); }
  140. static Counter& GetLargeHeapBlockFreeObjectSizeCounter() { return instance.GetCounter(8); }
  141. static Counter& GetSmallHeapBlockLiveObjectSizeCounter() { return instance.GetCounter(9); }
  142. static Counter& GetSmallHeapBlockLiveObjectCounter() { return instance.GetCounter(10); }
  143. static Counter& GetSmallHeapBlockFreeObjectSizeCounter() { return instance.GetCounter(11); }
  144. static Counter& GetLargeHeapBlockCountCounter() { return instance.GetCounter(12); }
  145. static Counter& GetLargeHeapBlockPageSizeCounter() { return instance.GetCounter(13); }
  146. private:
  147. static DefaultCounterSetInstance<RecyclerCounterSetDefinition> instance;
  148. };
  149. #endif
  150. #ifdef PROFILE_RECYCLER_ALLOC
  151. class RecyclerTrackerCounterSet
  152. {
  153. public:
  154. static Counter& GetPerfCounter(type_info const * typeinfo, bool isArray);
  155. static Counter& GetPerfSizeCounter(type_info const * typeinfo, bool isArray);
  156. static Counter& GetWeakRefPerfCounter(type_info const * typeinfo);
  157. class Map
  158. {
  159. public:
  160. Map(type_info const * type, bool isArray, uint counterIndex, uint sizeCounterIndex);
  161. Map(type_info const * type, uint weakRefCounterIndex);
  162. };
  163. private:
  164. static Counter& GetUnknownCounter() { return instance.GetCounter(0); }
  165. static Counter& GetUnknownSizeCounter() { return instance.GetCounter(1); }
  166. static Counter& GetUnknownArrayCounter() { return instance.GetCounter(2); }
  167. static Counter& GetUnknownArraySizeCounter() { return instance.GetCounter(3); }
  168. static Counter& GetUnknownWeakRefCounter() { return instance.GetCounter(4); }
  169. static DefaultCounterSetInstance<RecyclerTrackerCounterSetDefinition> instance;
  170. static uint const NumUnknownCounters = 5;
  171. static type_info const * CountIndexTypeInfoMap[RecyclerTrackerCounterSetDefinition::MaxCounter - NumUnknownCounters];
  172. static type_info const * SizeIndexTypeInfoMap[RecyclerTrackerCounterSetDefinition::MaxCounter - NumUnknownCounters];
  173. static type_info const * ArrayCountIndexTypeInfoMap[RecyclerTrackerCounterSetDefinition::MaxCounter - NumUnknownCounters];
  174. static type_info const * ArraySizeIndexTypeInfoMap[RecyclerTrackerCounterSetDefinition::MaxCounter - NumUnknownCounters];
  175. static type_info const * WeakRefIndexTypeInfoMap[RecyclerTrackerCounterSetDefinition::MaxCounter - NumUnknownCounters];
  176. };
  177. #define DEFINE_RECYCLER_TRACKER_PERF_COUNTER(type) \
  178. static PerfCounter::RecyclerTrackerCounterSet::Map RecyclerTrackerCounter##id(&typeid(type), false, \
  179. PerfCounter::RecyclerTrackerCounterSetDefinition::##type##CounterIndex, \
  180. PerfCounter::RecyclerTrackerCounterSetDefinition::##type##SizeCounterIndex)
  181. #define DEFINE_RECYCLER_TRACKER_ARRAY_PERF_COUNTER(type) \
  182. static PerfCounter::RecyclerTrackerCounterSet::Map RecyclerTrackerArrayCounter##id(&typeid(type), true, \
  183. PerfCounter::RecyclerTrackerCounterSetDefinition::##type##ArrayCounterIndex, \
  184. PerfCounter::RecyclerTrackerCounterSetDefinition::##type##ArraySizeCounterIndex)
  185. #define DEFINE_RECYCLER_TRACKER_WEAKREF_PERF_COUNTER(type) \
  186. static PerfCounter::RecyclerTrackerCounterSet::Map RecyclerTrackerWeakRefCounter##id(&typeid(type), \
  187. PerfCounter::RecyclerTrackerCounterSetDefinition::##type##WeakRefCounterIndex);
  188. #else
  189. #define DEFINE_RECYCLER_TRACKER_PERF_COUNTER(type)
  190. #define DEFINE_RECYCLER_TRACKER_ARRAY_PERF_COUNTER(type)
  191. #define DEFINE_RECYCLER_TRACKER_WEAKREF_PERF_COUNTER(type)
  192. #endif
  193. };
  194. #define PERF_COUNTER_INC(CounterSetName, CounterName) ++PerfCounter::CounterSetName##CounterSet::Get##CounterName##Counter()
  195. #define PERF_COUNTER_DEC(CounterSetName, CounterName) --PerfCounter::CounterSetName##CounterSet::Get##CounterName##Counter()
  196. #define PERF_COUNTER_ADD(CounterSetName, CounterName, value) PerfCounter::CounterSetName##CounterSet::Get##CounterName##Counter() += value
  197. #define PERF_COUNTER_SUB(CounterSetName, CounterName, value) PerfCounter::CounterSetName##CounterSet::Get##CounterName##Counter() -= value
  198. #else
  199. #define PERF_COUNTER_INC(CounterSetName, CounterName)
  200. #define PERF_COUNTER_DEC(CounterSetName, CounterName)
  201. #define PERF_COUNTER_ADD(CounterSetName, CounterName, value)
  202. #define PERF_COUNTER_SUB(CounterSetName, CounterName, value)
  203. #define DEFINE_RECYCLER_TRACKER_PERF_COUNTER(type)
  204. #define DEFINE_RECYCLER_TRACKER_ARRAY_PERF_COUNTER(type)
  205. #define DEFINE_RECYCLER_TRACKER_WEAKREF_PERF_COUNTER(type)
  206. #endif
  207. #ifdef HEAP_PERF_COUNTERS
  208. #define HEAP_PERF_COUNTER_INC(CounterName) PERF_COUNTER_INC(Heap, CounterName)
  209. #define HEAP_PERF_COUNTER_DEC(CounterName) PERF_COUNTER_DEC(Heap, CounterName)
  210. #define HEAP_PERF_COUNTER_ADD(CounterName, value) PERF_COUNTER_ADD(Heap, CounterName, value)
  211. #define HEAP_PERF_COUNTER_SUB(CounterName, value) PERF_COUNTER_SUB(Heap, CounterName, value)
  212. #else
  213. #define HEAP_PERF_COUNTER_INC(CounterName)
  214. #define HEAP_PERF_COUNTER_DEC(CounterName)
  215. #define HEAP_PERF_COUNTER_ADD(CounterName, value)
  216. #define HEAP_PERF_COUNTER_SUB(CounterName, value)
  217. #endif
  218. #ifdef RECYCLER_PERF_COUNTERS
  219. #define RECYCLER_PERF_COUNTER_INC(CounterName) PERF_COUNTER_INC(Recycler, CounterName)
  220. #define RECYCLER_PERF_COUNTER_DEC(CounterName) PERF_COUNTER_DEC(Recycler, CounterName)
  221. #define RECYCLER_PERF_COUNTER_ADD(CounterName, value) PERF_COUNTER_ADD(Recycler, CounterName, value)
  222. #define RECYCLER_PERF_COUNTER_SUB(CounterName, value) PERF_COUNTER_SUB(Recycler, CounterName, value)
  223. #else
  224. #define RECYCLER_PERF_COUNTER_INC(CounterName)
  225. #define RECYCLER_PERF_COUNTER_DEC(CounterName)
  226. #define RECYCLER_PERF_COUNTER_ADD(CounterName, value)
  227. #define RECYCLER_PERF_COUNTER_SUB(CounterName, value)
  228. #endif