EtwMemoryTracking.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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. #include "CommonMemoryPch.h"
  6. // xplat-todo: Need to figure out equivalent method for allocation tracing
  7. // on platforms other than Windows
  8. #ifdef ETW_MEMORY_TRACKING
  9. #include "microsoft-scripting-jscript9.internalevents.h"
  10. enum ArenaType: unsigned short
  11. {
  12. ArenaTypeRecycler = 1,
  13. ArenaTypeArena = 2
  14. };
  15. class EtwMemoryEvents
  16. {
  17. public:
  18. __declspec(noinline) static void ReportAllocation(void *arena, void *address, size_t size)
  19. {
  20. allocCount++;
  21. if (allocCount == 7500)
  22. {
  23. allocCount = 0;
  24. ::Sleep(350);
  25. }
  26. EventWriteJSCRIPT_INTERNAL_ALLOCATOR_ALLOC(arena, address, size);
  27. }
  28. __declspec(noinline) static void ReportFree(void *arena, void *address, size_t size)
  29. {
  30. EventWriteJSCRIPT_INTERNAL_ALLOCATOR_FREE(arena, address, size);
  31. }
  32. __declspec(noinline) static void ReportReallocation(void *arena, void *address, size_t existingSize, size_t newSize)
  33. {
  34. EventWriteJSCRIPT_INTERNAL_ALLOCATOR_FREE(arena, address, existingSize);
  35. EventWriteJSCRIPT_INTERNAL_ALLOCATOR_ALLOC(arena, address, newSize);
  36. }
  37. __declspec(noinline) static void ReportArenaCreated(void *arena, ArenaType arenaType)
  38. {
  39. EventWriteJSCRIPT_INTERNAL_ALLOCATOR_CREATE(arena, arenaType);
  40. }
  41. __declspec(noinline) static void ReportArenaDestroyed(void *arena)
  42. {
  43. EventWriteJSCRIPT_INTERNAL_ALLOCATOR_DESTROY(arena);
  44. }
  45. __declspec(noinline) static void ReportFreeAll(void *arena, ArenaType arenaType)
  46. {
  47. EventWriteJSCRIPT_INTERNAL_ALLOCATOR_DESTROY(arena);
  48. EventWriteJSCRIPT_INTERNAL_ALLOCATOR_CREATE(arena, arenaType);
  49. }
  50. private:
  51. static int allocCount;
  52. };
  53. int EtwMemoryEvents::allocCount = 0;
  54. // Workaround to stop the linker from collapsing the Arena/recycler methods to
  55. // a single implementation so that we have nicer stacks
  56. ArenaType g_arena;
  57. #define DISTINGUISH_FUNCTION(arenaType) g_arena = ArenaType##arenaType
  58. void ArenaMemoryTracking::Activate()
  59. {
  60. }
  61. __declspec(noinline) void ArenaMemoryTracking::ArenaCreated(Allocator *arena, __in LPCWSTR name)
  62. {
  63. DISTINGUISH_FUNCTION(Arena);
  64. EtwMemoryEvents::ReportArenaCreated(arena, ArenaTypeArena);
  65. }
  66. __declspec(noinline) void ArenaMemoryTracking::ArenaDestroyed(Allocator *arena)
  67. {
  68. DISTINGUISH_FUNCTION(Arena);
  69. EtwMemoryEvents::ReportArenaDestroyed(arena);
  70. }
  71. __declspec(noinline) void ArenaMemoryTracking::ReportAllocation(Allocator *arena, void *address, size_t size)
  72. {
  73. DISTINGUISH_FUNCTION(Arena);
  74. EtwMemoryEvents::ReportAllocation(arena, address, size);
  75. }
  76. __declspec(noinline) void ArenaMemoryTracking::ReportReallocation(Allocator *arena, void *address, size_t existingSize, size_t newSize)
  77. {
  78. DISTINGUISH_FUNCTION(Arena);
  79. EtwMemoryEvents::ReportReallocation(arena, address, existingSize, newSize);
  80. }
  81. __declspec(noinline) void ArenaMemoryTracking::ReportFree(Allocator *arena, void *address, size_t size)
  82. {
  83. DISTINGUISH_FUNCTION(Arena);
  84. EtwMemoryEvents::ReportFree(arena, address, size);
  85. }
  86. __declspec(noinline) void ArenaMemoryTracking::ReportFreeAll(Allocator *arena)
  87. {
  88. DISTINGUISH_FUNCTION(Arena);
  89. EtwMemoryEvents::ReportFreeAll(arena, ArenaTypeArena);
  90. }
  91. // Recycler tracking
  92. void RecyclerMemoryTracking::Activate()
  93. {
  94. }
  95. bool RecyclerMemoryTracking::IsActive()
  96. {
  97. return true;
  98. }
  99. // The external reporting for the recycler uses the MemspectMemoryTracker
  100. __declspec(noinline) void RecyclerMemoryTracking::ReportRecyclerCreate(Recycler * recycler)
  101. {
  102. DISTINGUISH_FUNCTION(Recycler);
  103. EtwMemoryEvents::ReportArenaCreated(recycler, ArenaTypeRecycler);
  104. }
  105. __declspec(noinline) void RecyclerMemoryTracking::ReportRecyclerDestroy(Recycler * recycler)
  106. {
  107. DISTINGUISH_FUNCTION(Recycler);
  108. EtwMemoryEvents::ReportArenaDestroyed(recycler);
  109. }
  110. __declspec(noinline) void RecyclerMemoryTracking::ReportAllocation(Recycler * recycler, __in void *address, size_t size)
  111. {
  112. DISTINGUISH_FUNCTION(Recycler);
  113. EtwMemoryEvents::ReportAllocation(recycler, address, size);
  114. }
  115. __declspec(noinline) void RecyclerMemoryTracking::ReportFree(Recycler * recycler, __in void *address, size_t size)
  116. {
  117. DISTINGUISH_FUNCTION(Recycler);
  118. EtwMemoryEvents::ReportFree(recycler, address, size);
  119. }
  120. void RecyclerMemoryTracking::ReportUnallocated(Recycler * recycler, __in void* address, __in void *endAddress, size_t sizeCat)
  121. {
  122. byte * byteAddress = (byte *) address;
  123. while (byteAddress + sizeCat <= endAddress)
  124. {
  125. EtwMemoryEvents::ReportAllocation(recycler, byteAddress, sizeCat);
  126. byteAddress += sizeCat;
  127. }
  128. }
  129. #endif