Skip to content

Commit 37128fe

Browse files
committed
Using multiple -on:flag -off:flag will correctly remove range from the opposite one
for instance, -off:FullJit -on:FullJit:1.4 -on:FullJit:1.5-1.8 will turn fulljit off for all functions except 1.4 & 1.5-1.8
1 parent 1a6bc8f commit 37128fe

5 files changed

Lines changed: 211 additions & 19 deletions

File tree

lib/Common/Core/CmdParser.cpp

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ CmdLineArgsParser::ParseInteger()
234234
///----------------------------------------------------------------------------
235235

236236
void
237-
CmdLineArgsParser::ParseRange(Js::Range *pRange)
237+
CmdLineArgsParser::ParseRange(Js::Range *pRange, Js::Range *oppositeRange)
238238
{
239239
SourceFunctionNode r1 = ParseSourceFunctionIds();
240240
SourceFunctionNode r2;
@@ -254,12 +254,12 @@ CmdLineArgsParser::ParseRange(Js::Range *pRange)
254254
throw Exception(_u("Left functionId must be smaller than the Right functionId when Source file is the same"));
255255
}
256256

257-
pRange->Add(r1, r2);
257+
pRange->Add(r1, r2, oppositeRange);
258258
switch(CurChar())
259259
{
260260
case ',':
261261
NextChar();
262-
ParseRange(pRange);
262+
ParseRange(pRange, oppositeRange);
263263
break;
264264

265265
case ' ':
@@ -272,14 +272,14 @@ CmdLineArgsParser::ParseRange(Js::Range *pRange)
272272
break;
273273

274274
case ',':
275-
pRange->Add(r1);
275+
pRange->Add(r1, oppositeRange);
276276
NextChar();
277-
ParseRange(pRange);
277+
ParseRange(pRange, oppositeRange);
278278
break;
279279

280280
case ' ':
281281
case 0:
282-
pRange->Add(r1);
282+
pRange->Add(r1, oppositeRange);
283283
break;
284284

285285
default:
@@ -350,7 +350,7 @@ CmdLineArgsParser::ParseNumberRange(Js::NumberRange *pRange)
350350
///----------------------------------------------------------------------------
351351

352352
void
353-
CmdLineArgsParser::ParsePhase(Js::Phases *pPhaseList)
353+
CmdLineArgsParser::ParsePhase(Js::Phases *pPhaseList, Js::Phases *oppositePhase)
354354
{
355355
char16 buffer[MaxTokenSize];
356356
ZeroMemory(buffer, sizeof(buffer));
@@ -365,14 +365,32 @@ CmdLineArgsParser::ParsePhase(Js::Phases *pPhaseList)
365365
switch(CurChar())
366366
{
367367
case ':':
368+
{
368369
NextChar();
369-
ParseRange(pPhaseList->GetRange(phase));
370+
Js::Range* oppositeRange = nullptr;
371+
if (oppositePhase && oppositePhase->IsEnabled(phase))
372+
{
373+
oppositeRange = oppositePhase->GetRange(phase);
374+
}
375+
ParseRange(pPhaseList->GetRange(phase), oppositeRange);
370376
break;
377+
}
371378
case ',':
372379
NextChar();
373-
ParsePhase(pPhaseList);
380+
if (oppositePhase)
381+
{
382+
// The whole phase is turned on/off so disable the opposite
383+
oppositePhase->Disable(phase);
384+
}
385+
ParsePhase(pPhaseList, oppositePhase);
374386
break;
375387
default:
388+
if (oppositePhase)
389+
{
390+
// The whole phase is turned on/off so disable the opposite
391+
oppositePhase->Disable(phase);
392+
}
393+
pPhaseList->GetRange(phase)->Clear();
376394
break;
377395
}
378396
}
@@ -512,8 +530,17 @@ CmdLineArgsParser::ParseFlag()
512530
switch(flagType)
513531
{
514532
case FlagPhases:
515-
ParsePhase(this->flagTable.GetAsPhase(flag));
533+
{
534+
Flag oppositeFlag = this->flagTable.GetOppositePhaseFlag(flag);
535+
Phases* oppositePhase = nullptr;
536+
if (oppositeFlag != InvalidFlag)
537+
{
538+
this->flagTable.Enable(oppositeFlag);
539+
oppositePhase = this->flagTable.GetAsPhase(oppositeFlag);
540+
}
541+
ParsePhase(this->flagTable.GetAsPhase(flag), oppositePhase);
516542
break;
543+
}
517544

518545
case FlagString:
519546
*this->flagTable.GetAsString(flag) = ParseString(buffer, MaxTokenSize, false);

lib/Common/Core/CmdParser.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ class CmdLineArgsParser : private ICmdLineArgsParser
6767
LPWSTR ParseString(__inout_ecount(ceBuffer) LPWSTR buffer, size_t ceBuffer = MaxTokenSize, bool fTreatColonAsSeparator = true);
6868
int ParseInteger();
6969
Js::SourceFunctionNode ParseSourceFunctionIds();
70-
void ParsePhase(Js::Phases *pPhase);
71-
void ParseRange(Js::Range *range);
70+
void ParsePhase(Js::Phases *pPhase, Js::Phases *oppositePhase);
71+
void ParseRange(Js::Range *range, Js::Range *oppositeRange);
7272
void ParseNumberRange(Js::NumberRange *range);
7373
void ParseFlag();
7474
void ParseNumberSet(Js::NumberSet * numberSet);

lib/Common/Core/ConfigFlagsTable.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,41 @@ namespace Js
141141
return false;
142142
}
143143

144+
template <>
145+
Js::RangeUnit<Js::SourceFunctionNode> GetFullRange()
146+
{
147+
RangeUnit<SourceFunctionNode> unit;
148+
unit.i.sourceContextId = 0;
149+
unit.j.sourceContextId = UINT_MAX;
150+
unit.i.functionId = 0;
151+
unit.j.functionId = (uint)-3;
152+
return unit;
153+
}
154+
155+
template <>
156+
SourceFunctionNode GetPrevious(SourceFunctionNode unit)
157+
{
158+
SourceFunctionNode prevUnit = unit;
159+
prevUnit.functionId--;
160+
if (prevUnit.functionId == UINT_MAX)
161+
{
162+
prevUnit.sourceContextId--;
163+
}
164+
return prevUnit;
165+
}
166+
167+
template <>
168+
SourceFunctionNode GetNext(SourceFunctionNode unit)
169+
{
170+
SourceFunctionNode nextUnit = unit;
171+
nextUnit.functionId++;
172+
if (nextUnit.functionId == 0)
173+
{
174+
nextUnit.sourceContextId++;
175+
}
176+
return nextUnit;
177+
}
178+
144179
///----------------------------------------------------------------------------
145180
///----------------------------------------------------------------------------
146181
///
@@ -181,6 +216,13 @@ namespace Js
181216
this->phaseList[(int)phase].valid = true;
182217
}
183218

219+
void
220+
Phases::Disable(Phase phase)
221+
{
222+
this->phaseList[(int)phase].valid = false;
223+
this->phaseList[(int)phase].range.Clear();
224+
}
225+
184226
Phase
185227
Phases::GetFirstPhase()
186228
{
@@ -308,6 +350,19 @@ namespace Js
308350
return reinterpret_cast<Phases*>(GetProperty(flag));
309351
}
310352

353+
Flag
354+
ConfigFlagsTable::GetOppositePhaseFlag(Flag flag) const
355+
{
356+
#if ENABLE_DEBUG_CONFIG_OPTIONS
357+
switch (flag)
358+
{
359+
case OnFlag: return OffFlag;
360+
case OffFlag: return OnFlag;
361+
}
362+
#endif
363+
return InvalidFlag;
364+
}
365+
311366
Boolean *
312367
ConfigFlagsTable::GetAsBoolean(Flag flag) const
313368
{

lib/Common/Core/ConfigFlagsTable.h

Lines changed: 116 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,36 @@ namespace Js
235235
template <>
236236
bool RangeUnitContains<SourceFunctionNode>(RangeUnit<SourceFunctionNode> unit, SourceFunctionNode n);
237237

238+
template <typename TRangeUnitData>
239+
RangeUnit<TRangeUnitData> GetFullRange()
240+
{
241+
RangeUnit<TRangeUnitData> unit;
242+
unit.i = INT_MIN;
243+
unit.j = INT_MAX;
244+
return unit;
245+
}
246+
247+
template <>
248+
RangeUnit<SourceFunctionNode> GetFullRange();
249+
250+
template <typename TRangeUnitData>
251+
TRangeUnitData GetPrevious(TRangeUnitData unit)
252+
{
253+
return unit - 1;
254+
}
255+
256+
template <>
257+
SourceFunctionNode GetPrevious(SourceFunctionNode unit);
258+
259+
template <typename TRangeUnitData>
260+
TRangeUnitData GetNext(TRangeUnitData unit)
261+
{
262+
return unit + 1;
263+
}
264+
265+
template <>
266+
SourceFunctionNode GetNext(SourceFunctionNode unit);
267+
238268
///----------------------------------------------------------------------------
239269
///----------------------------------------------------------------------------
240270
///
@@ -268,8 +298,9 @@ namespace Js
268298
public:
269299
inline bool InRange(TRangeUnitData i);
270300
inline bool ContainsAll();
271-
inline void Add(TRangeUnitData i);
272-
inline void Add(TRangeUnitData i, TRangeUnitData j);
301+
inline void Add(TRangeUnitData i, RangeBase<TRangeUnitData>* oppositeRange = nullptr);
302+
inline void Add(TRangeUnitData i, TRangeUnitData j, RangeBase<TRangeUnitData>* oppositeRange = nullptr);
303+
inline void Clear();
273304

274305
#if DBG_RANGE
275306
template <typename TFunction>
@@ -345,6 +376,7 @@ namespace Js
345376
public:
346377

347378
void Enable(Phase phase);
379+
void Disable(Phase phase);
348380
bool IsEnabled(Phase phase);
349381
bool IsEnabled(Phase phase, uint sourceContextId, Js::LocalFunctionId functionId);
350382
bool IsEnabledForAll(Phase phase);
@@ -394,6 +426,7 @@ namespace Js
394426

395427
String* GetAsString(Flag flag) const;
396428
Phases* GetAsPhase(Flag flag) const;
429+
Flag GetOppositePhaseFlag(Flag flag) const;
397430
Boolean* GetAsBoolean(Flag flag) const;
398431
Number* GetAsNumber(Flag flag) const;
399432
NumberSet* GetAsNumberSet(Flag flag) const;
@@ -812,16 +845,86 @@ namespace Js
812845

813846
template <typename TRangeUnitData>
814847
void
815-
RangeBase<TRangeUnitData>::Add(TRangeUnitData i)
848+
RangeBase<TRangeUnitData>::Add(TRangeUnitData i, RangeBase<TRangeUnitData>* oppositeRange)
816849
{
817-
Add(i, i);
850+
Add(i, i, oppositeRange);
818851
}
819852

820853
template <typename TRangeUnitData>
821854
void
822-
RangeBase<TRangeUnitData>::Add(TRangeUnitData i, TRangeUnitData j)
855+
RangeBase<TRangeUnitData>::Add(TRangeUnitData i, TRangeUnitData j, RangeBase<TRangeUnitData>* oppositeRange)
823856
{
824-
range.Prepend(RangeUnit<TRangeUnitData>(i, j));
857+
RangeUnit<TRangeUnitData> a(i, j);
858+
range.Prepend(a);
859+
if (oppositeRange)
860+
{
861+
if (oppositeRange->range.Empty())
862+
{
863+
oppositeRange->range.Prepend(GetFullRange<TRangeUnitData>());
864+
}
865+
// Do an intersection
866+
auto it = oppositeRange->range.GetEditingIterator();
867+
while (it.Next())
868+
{
869+
Unit& unit = it.Data();
870+
bool c1 = RangeUnitContains(unit, i);
871+
bool c2 = RangeUnitContains(unit, j);
872+
bool c3 = RangeUnitContains(a, unit.i);
873+
bool c4 = RangeUnitContains(a, unit.j);
874+
enum IntersectionCase
875+
{
876+
NoIntersection = 0,
877+
AddedFullyContained = 3, // [ u [a] ]
878+
IntersectionAdded_Unit = 6, // [ a [ ] u ]
879+
CommonLowBound_Unit = 7, // [[ a ] u ]
880+
IntersectionUnit_Added = 9, // [ u [ ] a ]
881+
CommonTopBound_Unit = 11, // [ u [ a ]]
882+
UnitFullyContained = 12, // [ a [u] ]
883+
CommonLowBound_Added = 13, // [[ u ] a ]
884+
CommonTopBound_Added = 14, // [ a [ u ]]
885+
FullIntersection = 15 // [[a, u]]
886+
};
887+
IntersectionCase intersectionCase = (IntersectionCase)((int)c1 | (c2 << 1) | (c3 << 2) | (c4 << 3));
888+
switch (intersectionCase)
889+
{
890+
case NoIntersection:
891+
// Nothing to do
892+
break;
893+
case AddedFullyContained:
894+
{
895+
// Need to break the current in 2
896+
Unit lowUnit = unit;
897+
Unit topUnit = unit;
898+
lowUnit.j = GetPrevious(a.i);
899+
topUnit.i = GetNext(a.j);
900+
it.InsertBefore(lowUnit);
901+
it.InsertBefore(topUnit);
902+
it.RemoveCurrent();
903+
break;
904+
}
905+
case IntersectionAdded_Unit:
906+
case CommonLowBound_Unit:
907+
// Move the unit lower bound after the added upper bound
908+
unit.i = GetNext(a.j);
909+
break;
910+
case IntersectionUnit_Added:
911+
case CommonTopBound_Unit:
912+
// Move the unit upper bound before the added lower bound
913+
unit.j = GetPrevious(a.i);
914+
break;
915+
case CommonTopBound_Added:
916+
case CommonLowBound_Added:
917+
case UnitFullyContained:
918+
case FullIntersection:
919+
// Remove the unit
920+
it.RemoveCurrent();
921+
break;
922+
default:
923+
Assert(UNREACHED);
924+
break;
925+
}
926+
}
927+
}
825928
}
826929

827930
template <typename TRangeUnitData>
@@ -831,6 +934,13 @@ RangeBase<TRangeUnitData>::ContainsAll()
831934
return range.Empty();
832935
}
833936

937+
template <typename TRangeUnitData>
938+
void
939+
Js::RangeBase<TRangeUnitData>::Clear()
940+
{
941+
range.Clear();
942+
}
943+
834944
///----------------------------------------------------------------------------
835945
///
836946
/// RangeBase::InRange

lib/Common/DataStructures/SList.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,7 @@ class SList : public SListBase<TData, TCount>
634634
{
635635
return __super::Remove(allocator, data);
636636
}
637-
637+
EditingIterator GetEditingIterator() { return EditingIterator(this); }
638638

639639
// Stack like interface
640640
bool Push(TData const& data)

0 commit comments

Comments
 (0)