| //------------------------------------------------------------------------------------------------------- |
| // Copyright (C) Microsoft. All rights reserved. |
| // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. |
| //------------------------------------------------------------------------------------------------------- |
| #include "RuntimeBasePch.h" |
| |
| #ifdef PROFILE_EXEC |
| #include "Base/ScriptContextProfiler.h" |
| |
| namespace Js |
| { |
| ULONG |
| ScriptContextProfiler::AddRef() |
| { |
| return refcount++; |
| } |
| |
| ULONG |
| ScriptContextProfiler::Release() |
| { |
| ULONG count = --refcount; |
| if (count == 0) |
| { |
| if (recycler != nullptr && this->profiler == recycler->GetProfiler()) |
| { |
| recycler->SetProfiler(nullptr, nullptr); |
| } |
| NoCheckHeapDelete(this); |
| } |
| return count; |
| } |
| |
| ScriptContextProfiler::ScriptContextProfiler() : |
| refcount(1), profilerArena(nullptr), profiler(nullptr), backgroundRecyclerProfilerArena(nullptr), backgroundRecyclerProfiler(nullptr), recycler(nullptr), pageAllocator(nullptr), next(nullptr) |
| { |
| } |
| |
| void |
| ScriptContextProfiler::Initialize(PageAllocator * pageAllocator, Recycler * recycler) |
| { |
| Assert(!IsInitialized()); |
| profilerArena = HeapNew(ArenaAllocator, _u("Profiler"), pageAllocator, Js::Throw::OutOfMemory); |
| profiler = Anew(profilerArena, Profiler, profilerArena); |
| if (recycler) |
| { |
| backgroundRecyclerProfilerArena = recycler->AddBackgroundProfilerArena(); |
| backgroundRecyclerProfiler = Anew(profilerArena, Profiler, backgroundRecyclerProfilerArena); |
| |
| #if DBG |
| //backgroundRecyclerProfiler is allocated from background and its guaranteed to assert below if we don't disable thread access check. |
| backgroundRecyclerProfiler->alloc->GetPageAllocator()->SetDisableThreadAccessCheck(); |
| #endif |
| |
| backgroundRecyclerProfiler->Begin(Js::AllPhase); |
| |
| #if DBG |
| backgroundRecyclerProfiler->alloc->GetPageAllocator()->SetEnableThreadAccessCheck(); |
| #endif |
| } |
| profiler->Begin(Js::AllPhase); |
| |
| this->recycler = recycler; |
| } |
| |
| void |
| ScriptContextProfiler::ProfilePrint(Js::Phase phase) |
| { |
| if (!IsInitialized()) |
| { |
| return; |
| } |
| profiler->End(Js::AllPhase); |
| profiler->Print(phase); |
| if (this->backgroundRecyclerProfiler) |
| { |
| this->backgroundRecyclerProfiler->End(Js::AllPhase); |
| this->backgroundRecyclerProfiler->Print(phase); |
| this->backgroundRecyclerProfiler->Begin(Js::AllPhase); |
| } |
| profiler->Begin(Js::AllPhase); |
| } |
| |
| ScriptContextProfiler::~ScriptContextProfiler() |
| { |
| if (profilerArena) |
| { |
| HeapDelete(profilerArena); |
| } |
| |
| if (recycler && backgroundRecyclerProfilerArena) |
| { |
| #if DBG |
| //We are freeing from main thread, disable thread check assert. |
| backgroundRecyclerProfilerArena->GetPageAllocator()->SetDisableThreadAccessCheck(); |
| #endif |
| recycler->ReleaseBackgroundProfilerArena(backgroundRecyclerProfilerArena); |
| } |
| } |
| |
| void |
| ScriptContextProfiler::ProfileBegin(Js::Phase phase) |
| { |
| Assert(IsInitialized()); |
| this->profiler->Begin(phase); |
| } |
| |
| void |
| ScriptContextProfiler::ProfileEnd(Js::Phase phase) |
| { |
| Assert(IsInitialized()); |
| this->profiler->End(phase); |
| } |
| |
| void |
| ScriptContextProfiler::ProfileSuspend(Js::Phase phase, Js::Profiler::SuspendRecord * suspendRecord) |
| { |
| Assert(IsInitialized()); |
| this->profiler->Suspend(phase, suspendRecord); |
| } |
| |
| void |
| ScriptContextProfiler::ProfileResume(Js::Profiler::SuspendRecord * suspendRecord) |
| { |
| Assert(IsInitialized()); |
| this->profiler->Resume(suspendRecord); |
| } |
| |
| void |
| ScriptContextProfiler::ProfileMerge(ScriptContextProfiler * profiler) |
| { |
| Assert(IsInitialized()); |
| this->profiler->Merge(profiler->profiler); |
| } |
| } |
| #endif |