Skip to content

Commit daa7431

Browse files
committed
remove the need of having a separate stack of ids that are being parsed by reusing the knowledge about whether given Id was already in the IncompleteObjects hash set or not
1 parent cd54d66 commit daa7431

File tree

1 file changed

+6
-12
lines changed
  • src/libraries/System.Resources.Extensions/src/System/Resources/Extensions/BinaryFormat/Deserializer

1 file changed

+6
-12
lines changed

src/libraries/System.Resources.Extensions/src/System/Resources/Extensions/BinaryFormat/Deserializer/Deserializer.cs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,6 @@ internal sealed partial class Deserializer : IDeserializer
7777
private Queue<PendingSerializationInfo>? _pendingSerializationInfo;
7878
private HashSet<SerializationRecordId>? _pendingSerializationInfoIds;
7979

80-
// Keeping a separate stack for ids for fast infinite loop checks.
81-
private readonly Stack<SerializationRecordId> _parseStack = [];
8280
private readonly Stack<ObjectRecordDeserializer> _parserStack = [];
8381

8482
/// <inheritdoc cref="IDeserializer.IncompleteObjects"/>
@@ -183,41 +181,36 @@ private object Deserialize()
183181
[RequiresUnreferencedCode("Calls DeserializeNew(SerializationRecordId)")]
184182
private void DeserializeRoot(SerializationRecordId rootId)
185183
{
186-
object root = DeserializeNew(rootId);
184+
object root = DeserializeNew(rootId, out _);
187185
if (root is not ObjectRecordDeserializer parser)
188186
{
189187
return;
190188
}
191189

192-
_parseStack.Push(rootId);
193190
_parserStack.Push(parser);
194191

195192
while (_parserStack.Count > 0)
196193
{
197194
ObjectRecordDeserializer? currentParser = _parserStack.Pop();
198-
SerializationRecordId currentId = _parseStack.Pop();
199-
Debug.Assert(currentId.Equals(currentParser.ObjectRecord.Id));
200195

201196
SerializationRecordId requiredId;
202197
while (!(requiredId = currentParser.Continue()).Equals(default(SerializationRecordId)))
203198
{
204199
// Beside ObjectRecordDeserializer, DeserializeNew can return a raw value like int, string or an array.
205-
if (DeserializeNew(requiredId) is ObjectRecordDeserializer requiredParser)
200+
if (DeserializeNew(requiredId, out bool wasAddedToIncompleteObjects) is ObjectRecordDeserializer requiredParser)
206201
{
207202
// The required object is not complete.
208203

209-
if (_parseStack.Contains(requiredId))
204+
if (!wasAddedToIncompleteObjects)
210205
{
211206
// All objects should be available before they're asked for a second time.
212207
throw new SerializationException(SR.Serialization_Cycle);
213208
}
214209

215210
// Push our current parser.
216-
_parseStack.Push(currentId);
217211
_parserStack.Push(currentParser);
218212

219213
// Push the required parser so we can complete it.
220-
_parseStack.Push(requiredId);
221214
_parserStack.Push(requiredParser);
222215

223216
break;
@@ -227,7 +220,7 @@ private void DeserializeRoot(SerializationRecordId rootId)
227220

228221
[MethodImpl(MethodImplOptions.AggressiveInlining)]
229222
[RequiresUnreferencedCode("Calls System.Windows.Forms.BinaryFormat.Deserializer.ObjectRecordParser.Create(SerializationRecordId, IRecord, IDeserializer)")]
230-
object DeserializeNew(SerializationRecordId id)
223+
object DeserializeNew(SerializationRecordId id, out bool wasAddedToIncompleteObjects)
231224
{
232225
// Strings, string arrays, and primitive arrays can be completed without creating a
233226
// parser object. Single primitives don't normally show up as records unless they are top
@@ -249,11 +242,12 @@ object DeserializeNew(SerializationRecordId id)
249242
if (value is not null)
250243
{
251244
_deserializedObjects.Add(record.Id, value);
245+
wasAddedToIncompleteObjects = false;
252246
return value;
253247
}
254248

255249
// Not a simple case, need to do a full deserialization of the record.
256-
_incompleteObjects.Add(id);
250+
wasAddedToIncompleteObjects = _incompleteObjects.Add(id);
257251

258252
var deserializer = ObjectRecordDeserializer.Create(record, this);
259253

0 commit comments

Comments
 (0)