ScriptContextProfiler.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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 "RuntimeBasePch.h"
  6. #ifdef PROFILE_EXEC
  7. #include "Base/ScriptContextProfiler.h"
  8. namespace Js
  9. {
  10. ULONG
  11. ScriptContextProfiler::AddRef()
  12. {
  13. return refcount++;
  14. }
  15. ULONG
  16. ScriptContextProfiler::Release()
  17. {
  18. ULONG count = --refcount;
  19. if (count == 0)
  20. {
  21. if (recycler != nullptr && this->profiler == recycler->GetProfiler())
  22. {
  23. recycler->SetProfiler(nullptr, nullptr);
  24. }
  25. NoCheckHeapDelete(this);
  26. }
  27. return count;
  28. }
  29. ScriptContextProfiler::ScriptContextProfiler() :
  30. refcount(1), profilerArena(nullptr), profiler(nullptr), backgroundRecyclerProfilerArena(nullptr), backgroundRecyclerProfiler(nullptr), recycler(nullptr), pageAllocator(nullptr), next(nullptr)
  31. {
  32. }
  33. void
  34. ScriptContextProfiler::Initialize(PageAllocator * pageAllocator, Recycler * recycler)
  35. {
  36. Assert(!IsInitialized());
  37. profilerArena = HeapNew(ArenaAllocator, _u("Profiler"), pageAllocator, Js::Throw::OutOfMemory);
  38. profiler = Anew(profilerArena, Profiler, profilerArena);
  39. if (recycler)
  40. {
  41. backgroundRecyclerProfilerArena = recycler->AddBackgroundProfilerArena();
  42. backgroundRecyclerProfiler = Anew(profilerArena, Profiler, backgroundRecyclerProfilerArena);
  43. #if DBG
  44. //backgroundRecyclerProfiler is allocated from background and its guaranteed to assert below if we don't disable thread access check.
  45. backgroundRecyclerProfiler->alloc->GetPageAllocator()->SetDisableThreadAccessCheck();
  46. #endif
  47. backgroundRecyclerProfiler->Begin(Js::AllPhase);
  48. #if DBG
  49. backgroundRecyclerProfiler->alloc->GetPageAllocator()->SetEnableThreadAccessCheck();
  50. #endif
  51. }
  52. profiler->Begin(Js::AllPhase);
  53. this->recycler = recycler;
  54. }
  55. void
  56. ScriptContextProfiler::ProfilePrint(Js::Phase phase)
  57. {
  58. if (!IsInitialized())
  59. {
  60. return;
  61. }
  62. profiler->End(Js::AllPhase);
  63. profiler->Print(phase);
  64. if (this->backgroundRecyclerProfiler)
  65. {
  66. this->backgroundRecyclerProfiler->End(Js::AllPhase);
  67. this->backgroundRecyclerProfiler->Print(phase);
  68. this->backgroundRecyclerProfiler->Begin(Js::AllPhase);
  69. }
  70. profiler->Begin(Js::AllPhase);
  71. }
  72. void
  73. ScriptContextProfiler::ProfilePrint()
  74. {
  75. Js::ScriptContextProfiler* profiler = this;
  76. if (Js::Configuration::Global.flags.Verbose)
  77. {
  78. //Print individual profiler information in verbose mode
  79. while (profiler)
  80. {
  81. profiler->ProfilePrint(Js::Configuration::Global.flags.Profile.GetFirstPhase());
  82. profiler = profiler->next;
  83. }
  84. }
  85. else
  86. {
  87. //Merge all the profiler for single snapshot.
  88. Js::ScriptContextProfiler* mergeToProfiler = profiler;
  89. // find the first initialized profiler
  90. while (mergeToProfiler != nullptr && !mergeToProfiler->IsInitialized())
  91. {
  92. mergeToProfiler = mergeToProfiler->next;
  93. }
  94. if (mergeToProfiler != nullptr)
  95. {
  96. // merge the rest profiler to the above initialized profiler
  97. profiler = mergeToProfiler->next;
  98. while (profiler)
  99. {
  100. if (profiler->IsInitialized())
  101. {
  102. mergeToProfiler->ProfileMerge(profiler);
  103. }
  104. profiler = profiler->next;
  105. }
  106. mergeToProfiler->ProfilePrint(Js::Configuration::Global.flags.Profile.GetFirstPhase());
  107. }
  108. }
  109. }
  110. ScriptContextProfiler::~ScriptContextProfiler()
  111. {
  112. if (profilerArena)
  113. {
  114. HeapDelete(profilerArena);
  115. }
  116. if (recycler && backgroundRecyclerProfilerArena)
  117. {
  118. #if DBG
  119. //We are freeing from main thread, disable thread check assert.
  120. backgroundRecyclerProfilerArena->GetPageAllocator()->SetDisableThreadAccessCheck();
  121. #endif
  122. recycler->ReleaseBackgroundProfilerArena(backgroundRecyclerProfilerArena);
  123. }
  124. }
  125. void
  126. ScriptContextProfiler::ProfileBegin(Js::Phase phase)
  127. {
  128. Assert(IsInitialized());
  129. this->profiler->Begin(phase);
  130. }
  131. void
  132. ScriptContextProfiler::ProfileEnd(Js::Phase phase)
  133. {
  134. Assert(IsInitialized());
  135. this->profiler->End(phase);
  136. }
  137. void
  138. ScriptContextProfiler::ProfileSuspend(Js::Phase phase, Js::Profiler::SuspendRecord * suspendRecord)
  139. {
  140. Assert(IsInitialized());
  141. this->profiler->Suspend(phase, suspendRecord);
  142. }
  143. void
  144. ScriptContextProfiler::ProfileResume(Js::Profiler::SuspendRecord * suspendRecord)
  145. {
  146. Assert(IsInitialized());
  147. this->profiler->Resume(suspendRecord);
  148. }
  149. void
  150. ScriptContextProfiler::ProfileMerge(ScriptContextProfiler * profiler)
  151. {
  152. Assert(IsInitialized());
  153. this->profiler->Merge(profiler->profiler);
  154. }
  155. }
  156. #endif