| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #include "CommonMemoryPch.h"
- // Initialization order
- // AB AutoSystemInfo
- // AD PerfCounter
- // AE PerfCounterSet
- // AM Output/Configuration
- // AN MemProtectHeap
- // AP DbgHelpSymbolManager
- // AQ CFGLogger
- // AR LeakReport
- // AS JavascriptDispatch/RecyclerObjectDumper
- // AT HeapAllocator/RecyclerHeuristic
- // AU RecyclerWriteBarrierManager
- #pragma warning(disable:4075) // initializers put in unrecognized initialization area on purpose
- #pragma init_seg(".CRT$XCAT")
- RecyclerHeuristic RecyclerHeuristic::Instance;
- // static
- RecyclerHeuristic::RecyclerHeuristic()
- {
- ::MEMORYSTATUSEX mem;
- mem.dwLength = sizeof(mem);
- BOOL isSuccess = ::GlobalMemoryStatusEx(&mem);
- Assert(isSuccess);
- DWORDLONG physicalMemoryBytes = mem.ullTotalPhys;
- uint baseFactor;
- // xplat-todo: Android sysconf is rather unreliable,
- // ullTotalPhys may not be the best source for a decision below
- if (isSuccess && AutoSystemInfo::IsLowMemoryDevice() && physicalMemoryBytes <= 512 MEGABYTES)
- {
- // Low-end Apollo (512MB RAM) scenario.
- // Note that what's specific about Apollo is that IE runs in physical memory,
- // that's one reason to distinguish 512MB Apollo from 512MB desktop.
- baseFactor = 16;
- this->DefaultMaxFreePageCount = 16 MEGABYTES_OF_PAGES;
- this->DefaultMaxAllocPageCount = 32;
- }
- else if (isSuccess && physicalMemoryBytes <= 1024 MEGABYTES)
- {
- // Tablet/slate/high-end Apollo scenario, including 512MB non-Apollo.
- baseFactor = 64;
- this->DefaultMaxFreePageCount = 64 MEGABYTES_OF_PAGES;
- this->DefaultMaxAllocPageCount = 64;
- }
- else
- {
- // Regular desktop scenario.
- baseFactor = 192;
- this->DefaultMaxFreePageCount = 512 MEGABYTES_OF_PAGES;
- this->DefaultMaxAllocPageCount = 256;
- }
- this->ConfigureBaseFactor(baseFactor);
- }
- void
- RecyclerHeuristic::ConfigureBaseFactor(uint baseFactor)
- {
- this->MaxUncollectedAllocBytes = baseFactor MEGABYTES;
- this->UncollectedAllocBytesConcurrentPriorityBoost = baseFactor MEGABYTES;
- this->MaxPartialUncollectedNewPageCount = baseFactor MEGABYTES_OF_PAGES;
- this->MaxUncollectedAllocBytesOnExit = (baseFactor / 2) MEGABYTES;
- this->MaxUncollectedAllocBytesPartialCollect = this->MaxUncollectedAllocBytes - 1 MEGABYTES;
- }
- uint
- RecyclerHeuristic::UncollectedAllocBytesCollection()
- {
- return DefaultUncollectedAllocBytesCollection;
- }
- #if ENABLE_CONCURRENT_GC
- uint
- RecyclerHeuristic::MaxBackgroundFinishMarkCount(Js::ConfigFlagsTable& flags)
- {
- #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
- if (flags.IsEnabled(Js::MaxBackgroundFinishMarkCountFlag))
- {
- return flags.MaxBackgroundFinishMarkCount;
- }
- #endif
- return DefaultMaxBackgroundFinishMarkCount;
- }
- DWORD
- RecyclerHeuristic::BackgroundFinishMarkWaitTime(bool backgroundFinishMarkWaitTime, Js::ConfigFlagsTable& flags)
- {
- if (RECYCLER_HEURISTIC_VERSION == 10)
- {
- backgroundFinishMarkWaitTime = backgroundFinishMarkWaitTime && CUSTOM_PHASE_ON1(flags, Js::BackgroundFinishMarkPhase);
- }
- else
- {
- backgroundFinishMarkWaitTime = backgroundFinishMarkWaitTime && !CUSTOM_PHASE_OFF1(flags, Js::BackgroundFinishMarkPhase);
- }
- if (!backgroundFinishMarkWaitTime && !CUSTOM_PHASE_FORCE1(flags, Js::BackgroundFinishMarkPhase))
- {
- return INFINITE;
- }
- #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
- if (flags.IsEnabled(Js::BackgroundFinishMarkWaitTimeFlag))
- {
- return flags.BackgroundFinishMarkWaitTime;
- }
- #endif
- if (CUSTOM_PHASE_FORCE1(flags, Js::BackgroundFinishMarkPhase))
- {
- return INFINITE;
- }
- return DefaultBackgroundFinishMarkWaitTime;
- }
- size_t
- RecyclerHeuristic::MinBackgroundRepeatMarkRescanBytes(Js::ConfigFlagsTable& flags)
- {
- #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
- if (flags.IsEnabled(Js::MinBackgroundRepeatMarkRescanBytesFlag))
- {
- return flags.MinBackgroundRepeatMarkRescanBytes;
- }
- #endif
- return DefaultMinBackgroundRepeatMarkRescanBytes;
- }
- DWORD
- RecyclerHeuristic::FinishConcurrentCollectWaitTime(Js::ConfigFlagsTable& flags)
- {
- #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
- if (flags.IsEnabled(Js::RecyclerThreadCollectTimeoutFlag))
- {
- return flags.RecyclerThreadCollectTimeout;
- }
- #endif
- return DefaultFinishConcurrentCollectWaitTime;
- }
- DWORD
- RecyclerHeuristic::PriorityBoostTimeout(Js::ConfigFlagsTable& flags)
- {
- #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
- if (flags.IsEnabled(Js::RecyclerPriorityBoostTimeoutFlag))
- {
- return flags.RecyclerPriorityBoostTimeout;
- }
- #endif
- return TickCountConcurrentPriorityBoost;
- }
- #endif
- #if ENABLE_PARTIAL_GC && ENABLE_CONCURRENT_GC
- bool
- RecyclerHeuristic::PartialConcurrentNextCollection(double ratio, Js::ConfigFlagsTable& flags)
- {
- if (CUSTOM_PHASE_FORCE1(flags, Js::ConcurrentPartialCollectPhase))
- {
- return true;
- }
- if (RECYCLER_HEURISTIC_VERSION == 10)
- {
- // Default off for version == 10
- if (!CUSTOM_PHASE_ON1(flags, Js::ConcurrentPartialCollectPhase))
- {
- return false;
- }
- }
- else
- {
- // Default on
- if (CUSTOM_PHASE_OFF1(flags, Js::ConcurrentPartialCollectPhase))
- {
- return false;
- }
- }
- return ratio >= 0.5;
- }
- #endif
|