memory_tracker.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. #ifndef __MEMORY_TRACKER_H
  2. #define __MEMORY_TRACKER_H
  3. #include "fixed_types.h"
  4. #include "lock.h"
  5. #include "routine_tracer.h"
  6. #include "cache_efficiency_tracker.h"
  7. #include <vector>
  8. #include <map>
  9. #include <unordered_map>
  10. // Define to add a slow checker for finding allocation sites by address
  11. //#define ASSERT_FIND_OWNER
  12. class MemoryTracker
  13. {
  14. public:
  15. // A light routine tracer that will activate the RoutineTracer infrastructure and allow us to get call stacks
  16. class RoutineTracerThread : public ::RoutineTracerThread
  17. {
  18. public:
  19. RoutineTracerThread(Thread *thread) : ::RoutineTracerThread(thread) {}
  20. const CallStack& getCallsiteStack() const { return m_callsite_stack; }
  21. protected:
  22. virtual void functionEnter(IntPtr eip, IntPtr callEip);
  23. virtual void functionExit(IntPtr eip);
  24. virtual void functionChildEnter(IntPtr eip, IntPtr eip_child) {}
  25. virtual void functionChildExit(IntPtr eip, IntPtr eip_child) {}
  26. private:
  27. CallStack m_callsite_stack;
  28. };
  29. class RoutineTracer : public ::RoutineTracer
  30. {
  31. public:
  32. RoutineTracer();
  33. virtual ~RoutineTracer();
  34. virtual RoutineTracerThread* getThreadHandler(Thread *thread) { return new RoutineTracerThread(thread); }
  35. virtual void addRoutine(IntPtr eip, const char *name, const char *imgname, IntPtr offset, int column, int line, const char *filename);
  36. virtual bool hasRoutine(IntPtr eip);
  37. virtual const Routine* getRoutineInfo(IntPtr eip) { return m_routines.count(eip) ? m_routines[eip] : NULL; }
  38. private:
  39. Lock m_lock;
  40. typedef std::unordered_map<IntPtr, RoutineTracer::Routine*> RoutineMap;
  41. RoutineMap m_routines;
  42. };
  43. MemoryTracker();
  44. ~MemoryTracker();
  45. void logMalloc(thread_id_t thread_id, UInt64 eip, UInt64 address, UInt64 size);
  46. void logFree(thread_id_t thread_id, UInt64 eip, UInt64 address);
  47. private:
  48. struct AllocationSite
  49. {
  50. AllocationSite()
  51. : num_allocations(0), total_size(0), total_loads(0), total_stores(0)
  52. , hit_where_load(HitWhere::NUM_HITWHERES, 0)
  53. , hit_where_store(HitWhere::NUM_HITWHERES, 0)
  54. {}
  55. UInt64 num_allocations;
  56. UInt64 total_size;
  57. UInt64 total_loads, total_stores;
  58. std::vector<UInt64> hit_where_load, hit_where_store;
  59. std::unordered_map<AllocationSite*, UInt64> evicted_by;
  60. };
  61. typedef std::unordered_map<CallStack, AllocationSite*> AllocationSites;
  62. struct Allocation
  63. {
  64. Allocation() : size(0), site(NULL) {}
  65. Allocation(UInt64 _size, AllocationSite* _site) : size(_size), site(_site) {}
  66. UInt64 size;
  67. AllocationSite *site;
  68. };
  69. typedef std::map<UInt64, Allocation> Allocations;
  70. Lock m_lock;
  71. Allocations m_allocations;
  72. AllocationSites m_allocation_sites;
  73. #ifdef ASSERT_FIND_OWNER
  74. std::unordered_map<UInt64, AllocationSite*> m_allocations_slow;
  75. #endif
  76. UInt64 ce_get_owner(core_id_t core_id, UInt64 address);
  77. void ce_notify_access(UInt64 owner, Core::mem_op_t mem_op_type, HitWhere::where_t hit_where);
  78. void ce_notify_evict(bool on_roi_end, UInt64 owner, UInt64 evictor, CacheBlockInfo::BitsUsedType bits_used, UInt32 bits_total);
  79. static UInt64 __ce_get_owner(UInt64 user, core_id_t core_id, UInt64 address)
  80. { return ((MemoryTracker*)user)->ce_get_owner(core_id, address); }
  81. static void __ce_notify_access(UInt64 user, UInt64 owner, Core::mem_op_t mem_op_type, HitWhere::where_t hit_where)
  82. { ((MemoryTracker*)user)->ce_notify_access(owner, mem_op_type, hit_where); }
  83. static void __ce_notify_evict(UInt64 user, bool on_roi_end, UInt64 owner, UInt64 evictor, CacheBlockInfo::BitsUsedType bits_used, UInt32 bits_total)
  84. { ((MemoryTracker*)user)->ce_notify_evict(on_roi_end, owner, evictor, bits_used, bits_total); }
  85. };
  86. #endif // __MEMORY_TRACKER_H