| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #include "Backend.h"
- #if ENABLE_OOP_NATIVE_CODEGEN
- #include "JITServer/JITServer.h"
- #include "PageAllocatorPool.h"
- CriticalSection PageAllocatorPool::cs;
- PageAllocatorPool* PageAllocatorPool::Instance = nullptr;
- PageAllocatorPool::PageAllocatorPool()
- :pageAllocators(&NoThrowHeapAllocator::Instance),
- idleCleanupTimer(NULL),
- activePageAllocatorCount(0)
- {
- idleCleanupTimer = CreateThreadpoolTimer(IdleCleanupRoutine, NULL, NULL);
- }
- PageAllocatorPool::~PageAllocatorPool()
- {
- AutoCriticalSection autoCS(&cs);
- RemoveAll();
- }
- void PageAllocatorPool::Initialize()
- {
- Instance = HeapNewNoThrow(PageAllocatorPool);
- if (Instance == nullptr)
- {
- Js::Throw::FatalInternalError();
- }
- }
- void PageAllocatorPool::Shutdown()
- {
- AutoCriticalSection autoCS(&cs);
- Assert(Instance);
- if (Instance)
- {
- PageAllocatorPool* localInstance = Instance;
- Instance = nullptr;
-
- if (localInstance->idleCleanupTimer)
- {
- CloseThreadpoolTimer(localInstance->idleCleanupTimer);
- }
- HeapDelete(localInstance);
- }
- }
- void PageAllocatorPool::RemoveAll()
- {
- Assert(cs.IsLocked());
- while (!pageAllocators.Empty())
- {
- HeapDelete(pageAllocators.Pop());
- }
- }
- unsigned int PageAllocatorPool::GetInactivePageAllocatorCount()
- {
- AutoCriticalSection autoCS(&cs);
- return pageAllocators.Count();
- }
- PageAllocator* PageAllocatorPool::GetPageAllocator()
- {
- AutoCriticalSection autoCS(&cs);
- PageAllocator* pageAllocator = nullptr;
- if (pageAllocators.Count() > 0)
- {
- // TODO: OOP JIT, select the page allocator with right count of free pages
- // base on some heuristic
- pageAllocator = this->pageAllocators.Pop();
- }
- else
- {
- pageAllocator = HeapNew(PageAllocator, nullptr, Js::Configuration::Global.flags, PageAllocatorType_BGJIT,
- AutoSystemInfo::Data.IsLowMemoryProcess() ? PageAllocator::DefaultLowMaxFreePageCount : PageAllocator::DefaultMaxFreePageCount);
- }
- activePageAllocatorCount++;
- return pageAllocator;
- }
- void PageAllocatorPool::ReturnPageAllocator(PageAllocator* pageAllocator)
- {
- AutoCriticalSection autoCS(&cs);
- if (!this->pageAllocators.PrependNoThrow(&NoThrowHeapAllocator::Instance, pageAllocator))
- {
- HeapDelete(pageAllocator);
- }
- activePageAllocatorCount--;
- if (activePageAllocatorCount == 0 || GetInactivePageAllocatorCount() > (uint)Js::Configuration::Global.flags.JITServerMaxInactivePageAllocatorCount)
- {
- PageAllocatorPool::IdleCleanup();
- }
- }
- void PageAllocatorPool::IdleCleanup()
- {
- AutoCriticalSection autoCS(&cs);
- if (Instance
- #ifdef PROFILE_EXEC
- // profiler keeps persistent reference to page allocators, so we can't cleanup on idle even if the allocators aren't currently being used for JIT
- && !Js::Configuration::Global.flags.IsEnabled(Js::ProfileFlag)
- #endif
- )
- {
- LARGE_INTEGER liDueTime;
- liDueTime.QuadPart = Js::Configuration::Global.flags.JITServerIdleTimeout * -10000LL; // wait for JITServerIdleTimeout milliseconds to do the cleanup
- if (Instance->idleCleanupTimer)
- {
- // Setting the timer cancels the previous timer, if any.
- SetThreadpoolTimer(Instance->idleCleanupTimer, (PFILETIME)&liDueTime, 0, 0);
- }
- else
- {
- Instance->RemoveAll();
- }
- }
- }
- VOID CALLBACK PageAllocatorPool::IdleCleanupRoutine(
- _Inout_ PTP_CALLBACK_INSTANCE,
- _Inout_opt_ PVOID,
- _Inout_ PTP_TIMER)
- {
- AutoCriticalSection autoCS(&cs);
- if (Instance)
- {
- // TODO: OOP JIT, use better stragtegy to do the cleanup, like do not remove all,
- // instead keep couple inactivate page allocator for next calls
- Instance->RemoveAll();
- }
- }
- #endif
|