| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #include "CommonCorePch.h"
- #include "Memory/PageHeapBlockTypeFilter.h"
- #include <initguid.h>
- #undef DebugBreak
- // 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$XCAM")
- namespace Js
- {
- NumberSet::NumberSet() : set(&NoCheckHeapAllocator::Instance) {}
- void NumberSet::Add(uint32 x)
- {
- set.Item(x);
- }
- bool NumberSet::Contains(uint32 x)
- {
- return set.Contains(x);
- }
- NumberPairSet::NumberPairSet() : set(&NoCheckHeapAllocator::Instance) {}
- void NumberPairSet::Add(uint32 x, uint32 y)
- {
- set.Item(NumberPair(x, y));
- }
- bool NumberPairSet::Contains(uint32 x, uint32 y)
- {
- return set.Contains(NumberPair(x, y));
- }
- NumberTrioSet::NumberTrioSet() : set(&NoCheckHeapAllocator::Instance) {}
- void NumberTrioSet::Add(uint32 x, uint32 y, uint32 z)
- {
- set.Item(NumberTrio(x, y, z));
- }
- bool NumberTrioSet::Contains(uint32 x, uint32 y, uint32 z)
- {
- return set.Contains(NumberTrio(x, y, z));
- }
- ///----------------------------------------------------------------------------
- ///----------------------------------------------------------------------------
- ///
- /// class String
- ///
- ///----------------------------------------------------------------------------
- ///----------------------------------------------------------------------------
- String::String()
- {
- this->pszValue = NULL;
- }
- String::String(__in_z_opt const char16* psz)
- {
- this->pszValue = NULL;
- Set(psz);
- }
- String::~String()
- {
- if(NULL != this->pszValue)
- {
- NoCheckHeapDeleteArray(wcslen(this->pszValue) + 1, this->pszValue);
- }
- }
- ///----------------------------------------------------------------------------
- ///
- /// String::Set
- ///
- /// Frees the existing string if any
- /// allocates a new buffer to copy the new string
- ///
- ///----------------------------------------------------------------------------
- void
- String::Set(__in_z_opt const char16* pszValue)
- {
- if(NULL != this->pszValue)
- {
- NoCheckHeapDeleteArray(wcslen(this->pszValue) + 1, this->pszValue);
- }
- if(NULL != pszValue)
- {
- size_t size = 1 + wcslen(pszValue);
- this->pszValue = NoCheckHeapNewArray(char16, size);
- wcscpy_s(this->pszValue, size, pszValue);
- }
- else
- {
- this->pszValue = NULL;
- }
- }
- template <>
- bool RangeUnitContains<SourceFunctionNode>(RangeUnit<SourceFunctionNode> unit, SourceFunctionNode n)
- {
- Assert(n.functionId != (uint32)-1);
- if ((n.sourceContextId >= unit.i.sourceContextId) &&
- (n.sourceContextId <= unit.j.sourceContextId)
- )
- {
- if ((n.sourceContextId == unit.j.sourceContextId && -2 == unit.j.functionId) || //#.#-#.* case
- (n.sourceContextId == unit.i.sourceContextId && -2 == unit.i.functionId) //#.*-#.# case
- )
- {
- return true;
- }
- if ((n.sourceContextId == unit.j.sourceContextId && -1 == unit.j.functionId) || //#.#-#.+ case
- (n.sourceContextId == unit.i.sourceContextId && -1 == unit.i.functionId) //#.+-#.# case
- )
- {
- return n.functionId != 0;
- }
- if ((n.sourceContextId == unit.i.sourceContextId && n.functionId < unit.i.functionId) || //excludes all values less than functionId LHS
- (n.sourceContextId == unit.j.sourceContextId && n.functionId > unit.j.functionId)) ////excludes all values greater than functionId RHS
- {
- return false;
- }
- return true;
- }
- return false;
- }
- template <>
- Js::RangeUnit<Js::SourceFunctionNode> GetFullRange()
- {
- RangeUnit<SourceFunctionNode> unit;
- unit.i.sourceContextId = 0;
- unit.j.sourceContextId = UINT_MAX;
- unit.i.functionId = 0;
- unit.j.functionId = (uint)-3;
- return unit;
- }
- template <>
- SourceFunctionNode GetPrevious(SourceFunctionNode unit)
- {
- SourceFunctionNode prevUnit = unit;
- prevUnit.functionId--;
- if (prevUnit.functionId == UINT_MAX)
- {
- prevUnit.sourceContextId--;
- }
- return prevUnit;
- }
- template <>
- SourceFunctionNode GetNext(SourceFunctionNode unit)
- {
- SourceFunctionNode nextUnit = unit;
- nextUnit.functionId++;
- if (nextUnit.functionId == 0)
- {
- nextUnit.sourceContextId++;
- }
- return nextUnit;
- }
- ///----------------------------------------------------------------------------
- ///----------------------------------------------------------------------------
- ///
- /// class Phases
- ///
- ///----------------------------------------------------------------------------
- ///----------------------------------------------------------------------------
- bool
- Phases::IsEnabled(Phase phase)
- {
- return this->phaseList[(int)phase].valid;
- }
- bool
- Phases::IsEnabled(Phase phase, uint sourceContextId, Js::LocalFunctionId functionId)
- {
- return this->phaseList[(int)phase].valid &&
- this->phaseList[(int)phase].range.InRange(SourceFunctionNode(sourceContextId, functionId));
- }
- bool
- Phases::IsEnabledForAll(Phase phase)
- {
- return this->phaseList[(int)phase].valid &&
- this->phaseList[(int)phase].range.ContainsAll();
- }
- Range *
- Phases::GetRange(Phase phase)
- {
- return &this->phaseList[(int)phase].range;
- }
- void
- Phases::Enable(Phase phase)
- {
- this->phaseList[(int)phase].valid = true;
- }
- void
- Phases::Disable(Phase phase)
- {
- this->phaseList[(int)phase].valid = false;
- this->phaseList[(int)phase].range.Clear();
- }
- Phase
- Phases::GetFirstPhase()
- {
- int i= -1;
- while(!this->phaseList[++i].valid)
- {
- if(i >= PhaseCount - 1)
- {
- return InvalidPhase;
- }
- }
- return Phase(i);
- }
- //
- // List of names of all the flags
- //
- const char16* const FlagNames[FlagCount + 1] =
- {
- #define FLAG(type, name, ...) _u(#name),
- #include "ConfigFlagsList.h"
- NULL
- #undef FLAG
- };
- //
- // List of names of all the Phases
- //
- const char16* const PhaseNames[PhaseCount + 1] =
- {
- #define PHASE(name) _u(#name),
- #include "ConfigFlagsList.h"
- NULL
- #undef PHASE
- };
- //
- // Description of flags
- //
- const char16* const FlagDescriptions[FlagCount + 1] =
- {
- #define FLAG(type, name, description, ...) _u(description),
- #include "ConfigFlagsList.h"
- NULL
- #undef FLAG
- };
- //
- // Parent flag categorization of flags
- //
- const Flag FlagParents[FlagCount + 1] =
- {
- #define FLAG(type, name, description, defaultValue, parentName, ...) parentName##Flag,
- #include "ConfigFlagsList.h"
- InvalidFlag
- #undef FLAG
- };
- ///
- ///----------------------------------------------------------------------------
- ///----------------------------------------------------------------------------
- ///
- /// class ConfigFlagsTable
- ///
- ///----------------------------------------------------------------------------
- ///----------------------------------------------------------------------------
- ///----------------------------------------------------------------------------
- ///
- /// ConfigFlagsTable::ConfigFlagsTable
- ///
- /// Constructor initializes all the flags with their default values. The nDummy
- /// variable is used to prevent the compiler error due to the trailing comma
- /// when we generate the list of flags.
- ///
- ///----------------------------------------------------------------------------
- #define FLAG(type, name, description, defaultValue, ...) \
- \
- name ## ( ## defaultValue ##), \
- ConfigFlagsTable::ConfigFlagsTable():
- #include "ConfigFlagsList.h"
- #undef FLAG
- nDummy(0)
- {
- for(int i=0; i < FlagCount; flagPresent[i++] = false);
- // set mark for parent flags
- ZeroMemory(this->flagIsParent, sizeof(this->flagIsParent));
- #define FLAG(type, name, description, defaultValue, parentName, ...) \
- if ((int)parentName##Flag < FlagCount) this->flagIsParent[(int) parentName##Flag] = true;
- #include "ConfigFlagsList.h"
- #undef FLAG
- // set all parent flags to their default (setting all child flags to their right values)
- this->SetAllParentFlagsAsDefaultValue();
- #if defined(ENABLE_DEBUG_CONFIG_OPTIONS) && CONFIG_PARSE_CONFIG_FILE
- rawInputFromConfigFileIndex = 0;
- memset(rawInputFromConfigFile, 0, sizeof(rawInputFromConfigFile));
- #endif
- }
- ///----------------------------------------------------------------------------
- ///
- /// ConfigFlagsTable::SetAllParentFlagsAsDefaultValue
- ///
- /// Iterate through all parent flags and set their default value
- ///
- /// Note: only Boolean type supported for now
- ///----------------------------------------------------------------------------
- String *
- ConfigFlagsTable::GetAsString(Flag flag) const
- {
- return reinterpret_cast<String* >(GetProperty(flag));
- }
- Phases *
- ConfigFlagsTable::GetAsPhase(Flag flag) const
- {
- return reinterpret_cast<Phases*>(GetProperty(flag));
- }
- Flag
- ConfigFlagsTable::GetOppositePhaseFlag(Flag flag) const
- {
- #if ENABLE_DEBUG_CONFIG_OPTIONS
- switch (flag)
- {
- case OnFlag: return OffFlag;
- case OffFlag: return OnFlag;
- }
- #endif
- return InvalidFlag;
- }
- Boolean *
- ConfigFlagsTable::GetAsBoolean(Flag flag) const
- {
- return reinterpret_cast<Boolean*>(GetProperty(flag));
- }
- Number *
- ConfigFlagsTable::GetAsNumber(Flag flag) const
- {
- return reinterpret_cast<Number* >(GetProperty(flag));
- }
- NumberSet *
- ConfigFlagsTable::GetAsNumberSet(Flag flag) const
- {
- return reinterpret_cast<NumberSet* >(GetProperty(flag));
- }
- NumberPairSet *
- ConfigFlagsTable::GetAsNumberPairSet(Flag flag) const
- {
- return reinterpret_cast<NumberPairSet* >(GetProperty(flag));
- }
- NumberTrioSet *
- ConfigFlagsTable::GetAsNumberTrioSet(Flag flag) const
- {
- return reinterpret_cast<NumberTrioSet*>(GetProperty(flag));
- }
- NumberRange *
- ConfigFlagsTable::GetAsNumberRange(Flag flag) const
- {
- return reinterpret_cast<NumberRange* >(GetProperty(flag));
- }
- void
- ConfigFlagsTable::Enable(Flag flag)
- {
- this->flagPresent[flag] = true;
- }
- void
- ConfigFlagsTable::Disable(Flag flag)
- {
- this->flagPresent[flag] = false;
- }
- bool
- ConfigFlagsTable::IsEnabled(Flag flag)
- {
- return this->flagPresent[flag];
- }
- bool
- ConfigFlagsTable::IsParentFlag(Flag flag) const
- {
- return this->flagIsParent[flag];
- }
- void
- ConfigFlagsTable::SetAllParentFlagsAsDefaultValue()
- {
- for (int i = 0; i < FlagCount; i++)
- {
- Flag currentFlag = (Flag) i;
- if (this->IsParentFlag(currentFlag))
- {
- // only supporting Boolean for now
- AssertMsg(this->GetFlagType(currentFlag) == FlagBoolean, "only supporting boolean flags as parent flags");
- Boolean defaultParentValue = this->GetDefaultValueAsBoolean(currentFlag);
- this->SetAsBoolean(currentFlag, defaultParentValue);
- }
- }
- }
- void ConfigFlagsTable::FinalizeConfiguration()
- {
- TransferAcronymFlagConfiguration();
- TranslateFlagConfiguration();
- }
- void ConfigFlagsTable::TransferAcronymFlagConfiguration()
- {
- // Transfer acronym flag configuration into the corresponding actual flag
- #define FLAG(...)
- #define FLAGNRA(Type, Name, Acronym, ...) \
- if(!IsEnabled(Name##Flag) && IsEnabled(Acronym##Flag)) \
- { \
- Enable(Name##Flag); \
- Name = Acronym; \
- }
- #if ENABLE_DEBUG_CONFIG_OPTIONS
- #define FLAGPRA(Type, ParentName, Name, Acronym, ...) \
- if(!IsEnabled(Name##Flag) && IsEnabled(Acronym##Flag)) \
- { \
- Enable(Name##Flag); \
- Name = Acronym; \
- }
- #define FLAGRA(Type, Name, Acronym, ...) FLAGNRA(Type, Name, Acronym, __VA_ARGS__)
- #endif
- #include "ConfigFlagsList.h"
- }
- void ConfigFlagsTable::TranslateFlagConfiguration()
- {
- const auto VerifyExecutionModeLimits = [this]()
- {
- const Number zero = static_cast<Number>(0);
- const Number maxUint8 = static_cast<Number>(static_cast<uint8>(-1)); // entry point call count is uint8
- const Number maxUint16 = static_cast<Number>(static_cast<uint16>(-1));
- #if ENABLE_DEBUG_CONFIG_OPTIONS
- Assert(MinInterpretCount >= zero);
- Assert(MinInterpretCount <= maxUint16);
- Assert(MaxInterpretCount >= zero);
- Assert(MaxInterpretCount <= maxUint16);
- Assert(MinSimpleJitRunCount >= zero);
- Assert(MinSimpleJitRunCount <= maxUint8);
- Assert(MaxSimpleJitRunCount >= zero);
- Assert(MaxSimpleJitRunCount <= maxUint8);
- Assert(SimpleJitAfter >= zero);
- Assert(SimpleJitAfter <= maxUint8);
- Assert(FullJitAfter >= zero);
- Assert(FullJitAfter <= maxUint16);
- #endif
- Assert(AutoProfilingInterpreter0Limit >= zero);
- Assert(AutoProfilingInterpreter0Limit <= maxUint16);
- Assert(ProfilingInterpreter0Limit >= zero);
- Assert(ProfilingInterpreter0Limit <= maxUint16);
- Assert(AutoProfilingInterpreter1Limit >= zero);
- Assert(AutoProfilingInterpreter1Limit <= maxUint16);
- Assert(SimpleJitLimit >= zero);
- Assert(SimpleJitLimit <= maxUint8);
- Assert(ProfilingInterpreter1Limit >= zero);
- Assert(ProfilingInterpreter1Limit <= maxUint16);
- Assert(
- (
- AutoProfilingInterpreter0Limit +
- ProfilingInterpreter0Limit +
- AutoProfilingInterpreter1Limit +
- SimpleJitLimit +
- ProfilingInterpreter1Limit
- ) <= maxUint16);
- };
- VerifyExecutionModeLimits();
- #if ENABLE_DEBUG_CONFIG_OPTIONS
- #if !DISABLE_JIT
- if(ForceDynamicProfile)
- {
- Force.Enable(DynamicProfilePhase);
- }
- if(ForceJITLoopBody)
- {
- Force.Enable(JITLoopBodyPhase);
- }
- #endif
- if(NoDeferParse)
- {
- Off.Enable(DeferParsePhase);
- }
- #endif
- #if ENABLE_DEBUG_CONFIG_OPTIONS && !DISABLE_JIT
- bool dontEnforceLimitsForSimpleJitAfterOrFullJitAfter = false;
- if((IsEnabled(MinInterpretCountFlag) || IsEnabled(MaxInterpretCountFlag)) &&
- !(IsEnabled(SimpleJitAfterFlag) || IsEnabled(FullJitAfterFlag)))
- {
- if(Off.IsEnabled(SimpleJitPhase))
- {
- Enable(FullJitAfterFlag);
- if(IsEnabled(MaxInterpretCountFlag))
- {
- FullJitAfter = MaxInterpretCount;
- }
- else
- {
- FullJitAfter = MinInterpretCount;
- dontEnforceLimitsForSimpleJitAfterOrFullJitAfter = true;
- }
- }
- else
- {
- Enable(SimpleJitAfterFlag);
- if(IsEnabled(MaxInterpretCountFlag))
- {
- SimpleJitAfter = MaxInterpretCount;
- }
- else
- {
- SimpleJitAfter = MinInterpretCount;
- dontEnforceLimitsForSimpleJitAfterOrFullJitAfter = true;
- }
- if((IsEnabled(MinInterpretCountFlag) && IsEnabled(MinSimpleJitRunCountFlag)) ||
- IsEnabled(MaxSimpleJitRunCountFlag))
- {
- Enable(FullJitAfterFlag);
- FullJitAfter = SimpleJitAfter;
- if(IsEnabled(MaxSimpleJitRunCountFlag))
- {
- FullJitAfter += MaxSimpleJitRunCount;
- }
- else
- {
- FullJitAfter += MinSimpleJitRunCount;
- Assert(dontEnforceLimitsForSimpleJitAfterOrFullJitAfter);
- }
- }
- }
- }
- // Configure execution mode limits
- do
- {
- if(IsEnabled(AutoProfilingInterpreter0LimitFlag) ||
- IsEnabled(ProfilingInterpreter0LimitFlag) ||
- IsEnabled(AutoProfilingInterpreter1LimitFlag) ||
- IsEnabled(SimpleJitLimitFlag) ||
- IsEnabled(ProfilingInterpreter1LimitFlag))
- {
- break;
- }
- if(IsEnabled(ExecutionModeLimitsFlag))
- {
- uint autoProfilingInterpreter0Limit;
- uint profilingInterpreter0Limit;
- uint autoProfilingInterpreter1Limit;
- uint simpleJitLimit;
- uint profilingInterpreter1Limit;
- const int scannedCount =
- swscanf_s(
- static_cast<LPCWSTR>(ExecutionModeLimits),
- _u("%u.%u.%u.%u.%u"),
- &autoProfilingInterpreter0Limit,
- &profilingInterpreter0Limit,
- &autoProfilingInterpreter1Limit,
- &simpleJitLimit,
- &profilingInterpreter1Limit);
- Assert(scannedCount == 5);
- Enable(AutoProfilingInterpreter0LimitFlag);
- Enable(ProfilingInterpreter0LimitFlag);
- Enable(AutoProfilingInterpreter1LimitFlag);
- Enable(SimpleJitLimitFlag);
- Enable(ProfilingInterpreter1LimitFlag);
- AutoProfilingInterpreter0Limit = autoProfilingInterpreter0Limit;
- ProfilingInterpreter0Limit = profilingInterpreter0Limit;
- AutoProfilingInterpreter1Limit = autoProfilingInterpreter1Limit;
- SimpleJitLimit = simpleJitLimit;
- ProfilingInterpreter1Limit = profilingInterpreter1Limit;
- break;
- }
- if(!NewSimpleJit)
- {
- // Use the defaults for old simple JIT. The flags are not enabled here because the values can be changed later
- // based on other flags, only the defaults values are adjusted here.
- AutoProfilingInterpreter0Limit = DEFAULT_CONFIG_AutoProfilingInterpreter0Limit;
- ProfilingInterpreter0Limit = DEFAULT_CONFIG_ProfilingInterpreter0Limit;
- CompileAssert(
- DEFAULT_CONFIG_AutoProfilingInterpreter0Limit <= DEFAULT_CONFIG_AutoProfilingInterpreterLimit_OldSimpleJit);
- AutoProfilingInterpreter1Limit =
- DEFAULT_CONFIG_AutoProfilingInterpreterLimit_OldSimpleJit - DEFAULT_CONFIG_AutoProfilingInterpreter0Limit;
- CompileAssert(DEFAULT_CONFIG_ProfilingInterpreter0Limit <= DEFAULT_CONFIG_SimpleJitLimit_OldSimpleJit);
- SimpleJitLimit = DEFAULT_CONFIG_SimpleJitLimit_OldSimpleJit - DEFAULT_CONFIG_ProfilingInterpreter0Limit;
- ProfilingInterpreter1Limit = 0;
- VerifyExecutionModeLimits();
- }
- if (IsEnabled(SimpleJitAfterFlag))
- {
- Enable(AutoProfilingInterpreter0LimitFlag);
- Enable(ProfilingInterpreter0LimitFlag);
- Enable(AutoProfilingInterpreter1LimitFlag);
- Enable(EnforceExecutionModeLimitsFlag);
- {
- Js::Number iterationsNeeded = SimpleJitAfter;
- ProfilingInterpreter0Limit = min(ProfilingInterpreter0Limit, iterationsNeeded);
- iterationsNeeded -= ProfilingInterpreter0Limit;
- AutoProfilingInterpreter0Limit = iterationsNeeded;
- AutoProfilingInterpreter1Limit = 0;
- }
- if(IsEnabled(FullJitAfterFlag))
- {
- Enable(SimpleJitLimitFlag);
- Enable(ProfilingInterpreter1LimitFlag);
- Assert(SimpleJitAfter <= FullJitAfter);
- Js::Number iterationsNeeded = FullJitAfter - SimpleJitAfter;
- Js::Number profilingIterationsNeeded =
- min(NewSimpleJit
- ? DEFAULT_CONFIG_MinProfileIterations
- : DEFAULT_CONFIG_MinProfileIterations_OldSimpleJit,
- FullJitAfter) -
- ProfilingInterpreter0Limit;
- if(NewSimpleJit)
- {
- ProfilingInterpreter1Limit = min(ProfilingInterpreter1Limit, iterationsNeeded);
- iterationsNeeded -= ProfilingInterpreter1Limit;
- profilingIterationsNeeded -= ProfilingInterpreter1Limit;
- SimpleJitLimit = iterationsNeeded;
- }
- else
- {
- SimpleJitLimit = iterationsNeeded;
- profilingIterationsNeeded -= min(SimpleJitLimit, profilingIterationsNeeded);
- ProfilingInterpreter1Limit = 0;
- }
- if(profilingIterationsNeeded != 0)
- {
- Js::Number iterationsToMove = min(AutoProfilingInterpreter1Limit, profilingIterationsNeeded);
- AutoProfilingInterpreter1Limit -= iterationsToMove;
- ProfilingInterpreter0Limit += iterationsToMove;
- profilingIterationsNeeded -= iterationsToMove;
- iterationsToMove = min(AutoProfilingInterpreter0Limit, profilingIterationsNeeded);
- AutoProfilingInterpreter0Limit -= iterationsToMove;
- ProfilingInterpreter0Limit += iterationsToMove;
- profilingIterationsNeeded -= iterationsToMove;
- Assert(profilingIterationsNeeded == 0);
- }
- Assert(
- (
- AutoProfilingInterpreter0Limit +
- ProfilingInterpreter0Limit +
- AutoProfilingInterpreter1Limit +
- SimpleJitLimit +
- ProfilingInterpreter1Limit
- ) == FullJitAfter);
- }
- Assert(
- (
- AutoProfilingInterpreter0Limit +
- ProfilingInterpreter0Limit +
- AutoProfilingInterpreter1Limit
- ) == SimpleJitAfter);
- EnforceExecutionModeLimits = true;
- break;
- }
- if(IsEnabled(FullJitAfterFlag))
- {
- Enable(AutoProfilingInterpreter0LimitFlag);
- Enable(ProfilingInterpreter0LimitFlag);
- Enable(AutoProfilingInterpreter1LimitFlag);
- Enable(SimpleJitLimitFlag);
- Enable(ProfilingInterpreter1LimitFlag);
- Enable(EnforceExecutionModeLimitsFlag);
- Js::Number iterationsNeeded = FullJitAfter;
- if(NewSimpleJit)
- {
- ProfilingInterpreter1Limit = min(ProfilingInterpreter1Limit, iterationsNeeded);
- iterationsNeeded -= ProfilingInterpreter1Limit;
- }
- else
- {
- ProfilingInterpreter1Limit = 0;
- SimpleJitLimit = min(SimpleJitLimit, iterationsNeeded);
- iterationsNeeded -= SimpleJitLimit;
- }
- ProfilingInterpreter0Limit = min(ProfilingInterpreter0Limit, iterationsNeeded);
- iterationsNeeded -= ProfilingInterpreter0Limit;
- if(NewSimpleJit)
- {
- SimpleJitLimit = min(SimpleJitLimit, iterationsNeeded);
- iterationsNeeded -= SimpleJitLimit;
- }
- AutoProfilingInterpreter0Limit = min(AutoProfilingInterpreter0Limit, iterationsNeeded);
- iterationsNeeded -= AutoProfilingInterpreter0Limit;
- AutoProfilingInterpreter1Limit = iterationsNeeded;
- Assert(
- (
- AutoProfilingInterpreter0Limit +
- ProfilingInterpreter0Limit +
- AutoProfilingInterpreter1Limit +
- SimpleJitLimit +
- ProfilingInterpreter1Limit
- ) == FullJitAfter);
- EnforceExecutionModeLimits = true;
- break;
- }
- if (IsEnabled(MaxTemplatizedJitRunCountFlag))
- {
- if (MaxTemplatizedJitRunCount >= 0)
- {
- MinTemplatizedJitRunCount = MaxTemplatizedJitRunCount;
- }
- }
- if (IsEnabled(MaxAsmJsInterpreterRunCountFlag))
- {
- if (MaxAsmJsInterpreterRunCount >= 0)
- {
- MinAsmJsInterpreterRunCount = MaxAsmJsInterpreterRunCount;
- }
- }
- } while(false);
- #endif
- if( (
- #ifdef ENABLE_PREJIT
- Prejit ||
- #endif
- ForceNative
- ) &&
- !NoNative)
- {
- Enable(AutoProfilingInterpreter0LimitFlag);
- Enable(ProfilingInterpreter0LimitFlag);
- Enable(AutoProfilingInterpreter1LimitFlag);
- Enable(EnforceExecutionModeLimitsFlag);
- // Override any relevant automatic configuration above
- AutoProfilingInterpreter0Limit = 0;
- ProfilingInterpreter0Limit = 0;
- AutoProfilingInterpreter1Limit = 0;
- #if ENABLE_DEBUG_CONFIG_OPTIONS
- if(Off.IsEnabled(SimpleJitPhase))
- {
- Enable(SimpleJitLimitFlag);
- Enable(ProfilingInterpreter1LimitFlag);
- SimpleJitLimit = 0;
- ProfilingInterpreter1Limit = 0;
- }
- #endif
- EnforceExecutionModeLimits = true;
- }
- VerifyExecutionModeLimits();
- }
- ///----------------------------------------------------------------------------
- ///
- /// ConfigFlagsTable::GetFlag
- ///
- /// Given a string finds the corresponding enum Flag. The comparison is case
- /// in-sensitive
- ///
- ///----------------------------------------------------------------------------
- Flag
- ConfigFlagsTable::GetFlag(__in LPCWSTR str)
- {
- for(int i=0; i < FlagCount; i++)
- {
- if(0 == _wcsicmp(str, FlagNames[i]))
- {
- return Flag(i);
- }
- }
- return InvalidFlag;
- }
- ///----------------------------------------------------------------------------
- ///
- /// ConfigFlagsTable::GetPhase
- ///
- /// Given a string finds the corresponding enum Phase. The comparison is case
- /// in-sensitive
- ///
- ///----------------------------------------------------------------------------
- Phase
- ConfigFlagsTable::GetPhase(__in LPCWSTR str)
- {
- for(int i=0; i < PhaseCount; i++)
- {
- if(0 == _wcsicmp(str, PhaseNames[i]))
- {
- return Phase(i);
- }
- }
- return InvalidPhase;
- }
- void
- ConfigFlagsTable::PrintUsageString()
- {
- Output::Print(_u("List of Phases:\n"));
- for(int i = 0; i < PhaseCount; i++)
- {
- if (i % 4 == 0)
- {
- Output::Print(_u("\n "));
- }
- Output::Print(_u("%-40ls "), PhaseNames[i]);
- }
- Output::Print(_u("\n\nList of flags:\n\n"));
- for(int i = 0; i < FlagCount; i++)
- {
- Output::Print(_u("%60ls "), FlagNames[i]);
- switch(GetFlagType(Flag(i)))
- {
- case InvalidFlagType:
- break;
- case FlagString:
- Output::Print(_u("[:String] "));
- break;
- case FlagPhases:
- Output::Print(_u("[:Phase] "));
- break;
- case FlagNumber:
- Output::Print(_u("[:Number] "));
- break;
- case FlagBoolean:
- Output::Print(_u(" "));
- break;
- case FlagNumberSet:
- Output::Print(_u("[:NumberSet] "));
- break;
- case FlagNumberPairSet:
- Output::Print(_u("[:NumberPairSet] "));
- break;
- case FlagNumberTrioSet:
- Output::Print(_u("[:NumberTrioSet] "));
- break;
- case FlagNumberRange:
- Output::Print(_u("[:NumberRange] "));
- break;
- default:
- Assert(false);
- __assume(false);
- }
- Output::Print(_u("%ls\n"), FlagDescriptions[i]);
- }
- }
- ///----------------------------------------------------------------------------
- ///
- /// ConfigFlagsTable::GetFlagType
- ///
- /// Given a flag it returns the type (PhaseFlag, StringFlag ...). This could
- /// easily have been a lookup table like FlagNames and PhaseNames but this
- /// seems more concise
- ///
- ///----------------------------------------------------------------------------
- FlagTypes
- ConfigFlagsTable::GetFlagType(Flag flag)
- {
- switch(flag)
- {
- #define FLAG(type, name, ...) \
- case name##Flag : \
- return Flag##type; \
- #include "ConfigFlagsList.h"
- default:
- return InvalidFlagType;
- }
- }
- ///----------------------------------------------------------------------------
- ///
- /// ConfigFlagsTable::GetProperty
- ///
- /// Get the field corresponding to the flag. used as an internal method for
- /// the various GetAs* methods.
- ///
- ///----------------------------------------------------------------------------
- void *
- ConfigFlagsTable::GetProperty(Flag flag) const
- {
- switch(flag)
- {
- #define FLAG(type, name, ...) \
- \
- case name##Flag : \
- return reinterpret_cast<void*>(const_cast<type*>(&##name)); \
- #include "ConfigFlagsList.h"
- default:
- return NULL;
- }
- }
- void
- ConfigFlagsTable::VerboseDump()
- {
- #define FLAG(type, name, ...) \
- if (IsEnabled(name##Flag)) \
- { \
- Output::Print(_u("-%s"), _u(#name)); \
- switch (Flag##type) \
- { \
- case FlagBoolean: \
- if (!*GetAsBoolean(name##Flag)) \
- { \
- Output::Print(_u("-")); \
- } \
- break; \
- case FlagString: \
- if (GetAsString(name##Flag) != nullptr) \
- { \
- Output::Print(_u(":%s"), (LPCWSTR)*GetAsString(name##Flag)); \
- } \
- break; \
- case FlagNumber: \
- Output::Print(_u(":%d"), *GetAsNumber(name##Flag)); \
- break; \
- default: \
- break; \
- }; \
- Output::Print(_u("\n")); \
- }
- #include "ConfigFlagsList.h"
- #undef FLAG
- }
- ///----------------------------------------------------------------------------
- ///
- /// ConfigFlagsTable::GetDefaultValueAsBoolean
- ///
- /// Get the default value of a given boolean flag. If the flag is not of boolean
- /// type, will assert on CHK or return FALSE on FRE.
- ///
- ///----------------------------------------------------------------------------
- Boolean
- ConfigFlagsTable::GetDefaultValueAsBoolean(Flag flag) const
- {
- Boolean retValue = FALSE;
- switch (flag)
- {
- #define FLAG(type, name, description, defaultValue, ...) FLAGDEFAULT##type(name, defaultValue)
- // define an overload for each FlagTypes - type
- // * all defaults we don't care about
- #define FLAGDEFAULTPhases(name, defaultValue)
- #define FLAGDEFAULTString(name, defaultValue)
- #define FLAGDEFAULTNumber(name, defaultValue)
- #define FLAGDEFAULTNumberSet(name, defaultValue)
- #define FLAGDEFAULTNumberRange(name, defaultValue)
- #define FLAGDEFAULTNumberPairSet(name, defaultValue)
- #define FLAGDEFAULTNumberTrioSet(name, defaultValue)
- // * and those we do care about
- #define FLAGDEFAULTBoolean(name, defaultValue) \
- case name##Flag: \
- retValue = (Boolean) defaultValue; \
- break; \
- #include "ConfigFlagsList.h"
- #undef FLAGDEFAULTBoolean
- #undef FLAGDEFAULTNumberRange
- #undef FLAGDEFAULTNumberPairSet
- #undef FLAGDEFAULTNumberTrioSet
- #undef FLAGDEFAULTNumberSet
- #undef FLAGDEFAULTNumber
- #undef FLAGDEFAULTString
- #undef FLAGDEFAULTPhases
- #undef FLAG
- #undef FLAGREGOVREXPBoolean
- #undef FLAGREGOVREXPNumberRange
- #undef FLAGREGOVREXPNumberPairSet
- #undef FLAGREGOVREXPNumberTrioSet
- #undef FLAGREGOVREXPNumberSet
- #undef FLAGREGOVREXPNumber
- #undef FLAGREGOVREXPString
- #undef FLAGREGOVREXPPhases
- #undef FLAGREGOVRBoolean
- #undef FLAGREGOVRNumberRange
- #undef FLAGREGOVRNumberPairSet
- #undef FLAGREGOVRNumberTrioSet
- #undef FLAGREGOVRNumberSet
- #undef FLAGREGOVRNumber
- #undef FLAGREGOVRString
- #undef FLAGREGOVRPhases
- default:
- // not found - or not a boolean flag
- Assert(false);
- }
- return retValue;
- }
- ///----------------------------------------------------------------------------
- ///
- /// ConfigFlagsTable::SetAsBoolean
- ///
- /// Set the value of a boolean flag. If the flag is a parent flag, all children flag
- // will be set accordingly.
- ///
- ///----------------------------------------------------------------------------
- void
- ConfigFlagsTable::SetAsBoolean(Flag flag, Boolean value)
- {
- AssertMsg(this->GetFlagType(flag) == FlagBoolean, "flag not a boolean type");
- Boolean* settingAsBoolean = this->GetAsBoolean(flag);
- Assert(settingAsBoolean != nullptr);
- Output::VerboseNote(_u("FLAG %s = %d\n"), FlagNames[(int) flag], value);
- *settingAsBoolean = value;
- // check if parent flag
- if (this->IsParentFlag(flag))
- {
- // parent flag, will iterate through all child flags
- Flag childFlag = GetNextChildFlag(flag, /* no currentChildFlag */ InvalidFlag);
- while (childFlag != InvalidFlag)
- {
- Boolean childDefaultValue = GetDefaultValueAsBoolean(childFlag);
- // if the parent flag is TRUE, the children flag values are based on their default values
- // if the parent flag is FALSE, the children flag values are FALSE (always - as disabled)
- Boolean childValue = value == TRUE ? childDefaultValue : FALSE;
- Output::VerboseNote(_u("FLAG %s = %d - setting child flag %s = %d\n"), FlagNames[(int) flag], value, FlagNames[(int) childFlag], childValue);
- this->SetAsBoolean(childFlag, childValue);
- // get next child flag
- childFlag = GetNextChildFlag(flag, /* currentChildFlag */ childFlag);
- }
- }
- #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
- // in case the flag is marked as 'callback' - to call the method
- #define FLAG(type, name, description, defaultValue, parentName, hasCallback) FLAGCALLBACK##hasCallback(type, name)
- #define FLAGCALLBACKFALSE(type, name)
- #define FLAGCALLBACKTRUE(type, name) FLAGDOCALLBACK##type(name)
- // define an overload for each FlagTypes - type
- // * all defaults we don't care about - should assert
- #define FLAGDOCALLBACKNumberRange(name) Assert(false);
- #define FLAGDOCALLBACKPhases(name) Assert(false);
- #define FLAGDOCALLBACKString(name) Assert(false);
- #define FLAGDOCALLBACKNumber(name) Assert(false);
- #define FLAGDOCALLBACKNumberSet(name) Assert(false);
- #define FLAGDOCALLBACKNumberPairSet(name) Assert(false);
- #define FLAGDOCALLBACKNumberTrioSet(name) Assert(false);
- // * and those we do care about
- #define FLAGDOCALLBACKBoolean(name) if( flag == name##Flag ) this->FlagSetCallback_##name(value);
- #include "ConfigFlagsList.h"
- #undef FLAGDOCALLBACKBoolean
- #undef FLAGDOCALLBACKNumberRange
- #undef FLAGDOCALLBACKNumberPairSet
- #undef FLAGDOCALLBACKNumberTrioSet
- #undef FLAGDOCALLBACKNumberSet
- #undef FLAGDOCALLBACKNumber
- #undef FLAGDOCALLBACKString
- #undef FLAGDOCALLBACKPhases
- #undef FLAGCALLBACKTRUE
- #undef FLAGCALLBACKFALSE
- #undef FLAG
- #endif
- }
- ///----------------------------------------------------------------------------
- ///
- /// ConfigFlagsTable::GetParentFlag
- ///
- /// Get the parent flag corresponding to the flag, if any, otherwise returns NoParentFlag
- ///
- ///----------------------------------------------------------------------------
- Flag
- ConfigFlagsTable::GetParentFlag(Flag flag) const
- {
- Flag parentFlag = FlagParents[(int)flag];
- return parentFlag;
- }
- ///----------------------------------------------------------------------------
- ///
- /// ConfigFlagsTable::GetNextChildFlag
- ///
- /// Get the next child flag for a given parent flag. If no currentChildFlag, use
- /// InvalidFlag or NoParentFlag as start iterator.
- ///
- ///----------------------------------------------------------------------------
- Flag
- ConfigFlagsTable::GetNextChildFlag(Flag parentFlag, Flag currentChildFlag) const
- {
- // start at the current+1
- int startIndex = (int)currentChildFlag + 1;
- // otherwise start from beginning
- if (currentChildFlag == InvalidFlag || currentChildFlag == NoParentFlag)
- {
- // reset the start index
- startIndex = 0;
- }
- for(int i=startIndex; i < FlagCount; i++)
- {
- Flag currentFlag = (Flag)i;
- Flag parentFlagForCurrentFlag = GetParentFlag(currentFlag);
- if(parentFlagForCurrentFlag == parentFlag)
- {
- // found a match
- return currentFlag;
- }
- }
- // no more
- return InvalidFlag;
- }
- #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
- //
- // Special overrides for flags being set
- //
- void
- ConfigFlagsTable::FlagSetCallback_ES6All(Boolean value)
- {
- // iterate through all ES6 flags - and set them explicitly (except ES6Verbose)
- Flag parentFlag = ES6Flag;
- // parent ES6 flag, will iterate through all child ES6 flags
- Flag childFlag = GetNextChildFlag(parentFlag, /* no currentChildFlag */ InvalidFlag);
- while (childFlag != InvalidFlag)
- {
- // skip verbose
- if (childFlag != ES6VerboseFlag)
- {
- Boolean childValue = value;
- Output::VerboseNote(_u("FLAG %s = %d - setting child flag %s = %d\n"), FlagNames[(int) parentFlag], value, FlagNames[(int) childFlag], childValue);
- this->SetAsBoolean(childFlag, childValue);
- }
- // get next child flag
- childFlag = GetNextChildFlag(parentFlag, /* currentChildFlag */ childFlag);
- }
- }
- void
- ConfigFlagsTable::FlagSetCallback_ES6Experimental(Boolean value)
- {
- if (value)
- {
- EnableExperimentalFlag();
- }
- }
- #endif
- void
- ConfigFlagsTable::EnableExperimentalFlag()
- {
- AutoCriticalSection autocs(&csExperimentalFlags);
- #define FLAG_EXPERIMENTAL(type, name, ...) this->SetAsBoolean(Js::Flag::name##Flag, true);
- #include "ConfigFlagsList.h"
- }
- //
- // Configuration options
- //
- Configuration::Configuration()
- {
- }
- bool Configuration::EnableJitInDebugMode()
- {
- return CONFIG_FLAG(EnableJitInDiagMode);
- }
- Configuration Configuration::Global;
- } //namespace Js
|