-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Track state separately in NullableWalker for nested and containing methods #50417
Changes from 6 commits
cf5caa3
9a350d3
648b8e4
a7b4e52
0cfc45e
53e3149
c65c6e1
686fcb8
5baa27d
2b2e452
62a48fa
8402ec6
317d29e
6eb222d
e5c45e9
8a174ea
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,7 @@ | |
#define REFERENCE_STATE | ||
#endif | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Collections.Immutable; | ||
using System.Diagnostics; | ||
|
@@ -38,6 +39,29 @@ internal partial class DefiniteAssignmentPass : LocalDataFlowPass< | |
DefiniteAssignmentPass.LocalState, | ||
DefiniteAssignmentPass.LocalFunctionState> | ||
{ | ||
/// <summary> | ||
/// A mapping from local variables to the index of their slot in a flow analysis local state. | ||
/// </summary> | ||
private readonly PooledDictionary<VariableIdentifier, int> _variableSlot = PooledDictionary<VariableIdentifier, int>.GetInstance(); | ||
|
||
/// <summary> | ||
/// A mapping from the local variable slot to the symbol for the local variable itself. This | ||
/// is used in the implementation of region analysis (support for extract method) to compute | ||
/// the set of variables "always assigned" in a region of code. | ||
/// | ||
/// The first slot, slot 0, is reserved for indicating reachability, so the first tracked variable will | ||
/// be given slot 1. When referring to VariableIdentifier.ContainingSlot, slot 0 indicates | ||
/// that the variable in VariableIdentifier.Symbol is a root, i.e. not nested within another | ||
/// tracked variable. Slots less than 0 are illegal. | ||
/// </summary> | ||
protected readonly ArrayBuilder<VariableIdentifier> variableBySlot = ArrayBuilder<VariableIdentifier>.GetInstance(1, default); | ||
|
||
/// <summary> | ||
/// Variable slots are allocated to local variables sequentially and never reused. This is | ||
/// the index of the next slot number to use. | ||
/// </summary> | ||
protected int nextVariableSlot = 1; | ||
|
||
/// <summary> | ||
/// Some variables that should be considered initially assigned. Used for region analysis. | ||
/// </summary> | ||
|
@@ -192,6 +216,8 @@ internal DefiniteAssignmentPass( | |
|
||
protected override void Free() | ||
{ | ||
variableBySlot.Free(); | ||
_variableSlot.Free(); | ||
_usedVariables.Free(); | ||
_readParameters?.Free(); | ||
_usedLocalFunctions.Free(); | ||
|
@@ -204,6 +230,51 @@ protected override void Free() | |
base.Free(); | ||
} | ||
|
||
protected override bool TryGetVariable(VariableIdentifier identifier, out int slot) | ||
{ | ||
return _variableSlot.TryGetValue(identifier, out slot); | ||
} | ||
|
||
protected override int AddVariable(VariableIdentifier identifier) | ||
{ | ||
int slot = nextVariableSlot++; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Would it make sense to get rid of this field altogether? Can we simply look at |
||
_variableSlot.Add(identifier, slot); | ||
while (slot >= variableBySlot.Count) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Is there ever a case when we are not doing exactly one iteration? #Closed |
||
{ | ||
variableBySlot.Add(default); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
In reply to: 560532232 [](ancestors = 560532232) |
||
} | ||
variableBySlot[slot] = identifier; | ||
return slot; | ||
} | ||
|
||
protected Symbol GetNonMemberSymbol(int slot) | ||
{ | ||
VariableIdentifier variableId = variableBySlot[slot]; | ||
while (variableId.ContainingSlot > 0) | ||
{ | ||
Debug.Assert(variableId.Symbol.Kind == SymbolKind.Field || variableId.Symbol.Kind == SymbolKind.Property || variableId.Symbol.Kind == SymbolKind.Event, | ||
"inconsistent property symbol owner"); | ||
variableId = variableBySlot[variableId.ContainingSlot]; | ||
} | ||
return variableId.Symbol; | ||
} | ||
|
||
private int RootSlot(int slot) | ||
{ | ||
while (true) | ||
{ | ||
int containingSlot = variableBySlot[slot].ContainingSlot; | ||
if (containingSlot == 0) | ||
{ | ||
return slot; | ||
} | ||
else | ||
{ | ||
slot = containingSlot; | ||
} | ||
} | ||
} | ||
|
||
#if DEBUG | ||
protected override void VisitRvalue(BoundExpression node, bool isKnownToBeAnLvalue = false) | ||
{ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks naming of new fields is inconsistent around the use of "_". #Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These fields were moved from the base class, with the names unchanged. The names having a leading underscore for
private
fields, and no underscore forprotected
fields.In reply to: 561371496 [](ancestors = 561371496)