public bool CreateForwardReferences(ClrHeap heap, out string error) { const string progressHeader = Constants.HeavyAsteriskHeader + "[FwdRefs] "; error = null; int nullCount = 0; BinaryWriter bwFwdRefs = null, bwFwdOffs = null; _reflagSet = new BitSet(_instances.Length); //_reflagSet = new HashSet<int>(); try { _stopWatch = new Stopwatch(); _stopWatch.Start(); _progress?.Report(progressHeader + "Creating forward references data..."); _reversedRefsCounts = new int[_instances.Length]; _forwardRefsCounts = new int[_instances.Length]; int lastInstanceNdx = _instances.Length - 1; // for binary search bwFwdRefs = GetWriter(RefFile.FwdRefs, FileMode.Create); bwFwdOffs = GetWriter(RefFile.FwdOffsets, FileMode.Create); long offset = 0L; var fieldAddrOffsetList = new List <ulong>(64); for (int i = 0, icnt = _instances.Length; i < icnt; ++i) { var addr = Utils.RealAddress(_instances[i]); var clrType = heap.GetObjectType(addr); //Debug.Assert(clrType != null); // TODO JRD restore this bwFwdOffs.Write(offset); if (clrType == null) { ++nullCount; continue; } if (TypeExtractor.IsExludedType(clrType.Name)) { continue; } fieldAddrOffsetList.Clear(); clrType.EnumerateRefsOfObjectCarefully(addr, (address, off) => { fieldAddrOffsetList.Add(address); }); if (fieldAddrOffsetList.Count < 1) { continue; } int acount = PreprocessParentRefs(addr, fieldAddrOffsetList); if (acount == 0) { continue; } offset += acount * sizeof(int); _forwardRefsCounts[i] += acount; int parentNdx = Utils.AddressSearch(_instances, addr); Debug.Assert(parentNdx >= 0); for (int j = 0; j < acount; ++j) { ulong childAddr = fieldAddrOffsetList[j]; int childNdx = Utils.AddressSearch(_instances, childAddr); Debug.Assert(childNdx >= 0); if (copy_addr_flags_check(_instances, parentNdx, childNdx)) { _reflagSet.Set(childNdx); //_reflagSet.Add(childNdx); } _reversedRefsCounts[childNdx] += 1; // update reversed references count ++_totalReversedRefs; bwFwdRefs.Write(childNdx); } } bwFwdOffs.Write(offset); _progress?.Report(progressHeader + "Creating forward references data done. " + Utils.StopAndGetDurationStringAndRestart(_stopWatch)); _progress?.Report(progressHeader + "UNEXPECTED NULLS, count: " + nullCount); return(true); } catch (Exception ex) { error = Utils.GetExceptionErrorString(ex); _progress?.Report(progressHeader + "EXCEPTION: " + ex.Message); return(false); } finally { bwFwdRefs?.Close(); bwFwdOffs?.Close(); } }