Fix bugs from trying to get transitions for untracked slots when it's not supposed to
authorAmy Yu <amycmyu@gmail.com>
Fri, 15 Jun 2018 20:00:15 +0000 (13:00 -0700)
committerAmy Yu <amycmyu@gmail.com>
Fri, 15 Jun 2018 20:01:30 +0000 (13:01 -0700)
Commit migrated from https://github.com/dotnet/coreclr/commit/40f0203513823cb52daa352ae0f444cbc2b6daea

src/coreclr/src/tools/r2rdump/GCInfo.cs
src/coreclr/src/tools/r2rdump/GCInfoTypes.cs
src/coreclr/src/tools/r2rdump/GCSlotTable.cs

index 1dce78b..e924d40 100644 (file)
@@ -209,7 +209,7 @@ namespace R2RDump
 
             SlotTable = new GcSlotTable(image, machine, _gcInfoTypes, ref bitOffset);
 
-            Transitions = GetTranstions(image, SlotTable.GcSlots, ref bitOffset);
+            Transitions = GetTranstions(image, ref bitOffset);
 
             Size = bitOffset - startBitOffset;
 
@@ -359,7 +359,7 @@ namespace R2RDump
             return (readyToRunMajorVersion == 1) ? 1 : GCINFO_VERSION;
         }
 
-        public IList<GcTransition> GetTranstions(byte[] image, List<GcSlotTable.GcSlot> slots, ref int bitOffset)
+        public IList<GcTransition> GetTranstions(byte[] image, ref int bitOffset)
         {
             int totalInterruptibleLength = 0;
             if (NumInterruptibleRanges == 0)
@@ -389,7 +389,7 @@ namespace R2RDump
             int info2Offset = (int)Math.Ceiling(bitOffset / 8.0) * 8;
 
             List<GcTransition> transitions = new List<GcTransition>();
-            bool[] liveAtEnd = new bool[slots.Count];
+            bool[] liveAtEnd = new bool[SlotTable.GcSlots.Count - SlotTable.NumUntracked];
             for (int currentChunk = 0; currentChunk < numChunks; currentChunk++)
             {
                 if (chunkPointers[currentChunk] == 0)
@@ -412,7 +412,7 @@ namespace R2RDump
                     slotId = -1;
                 }
 
-                uint numCouldBeLiveSlots = GetNumCouldBeLiveSlots(image, slots, ref bitOffset);
+                uint numCouldBeLiveSlots = GetNumCouldBeLiveSlots(image, ref bitOffset);
 
                 int finalStateOffset = bitOffset;
                 bitOffset += (int)numCouldBeLiveSlots;
@@ -442,10 +442,10 @@ namespace R2RDump
             return transitions;
         }
 
-        private uint GetNumCouldBeLiveSlots(byte[] image, List<GcSlotTable.GcSlot> slots, ref int bitOffset)
+        private uint GetNumCouldBeLiveSlots(byte[] image, ref int bitOffset)
         {
             uint numCouldBeLiveSlots = 0;
-            int numSlots = slots.Count;
+            int numTracked = SlotTable.GcSlots.Count - (int)SlotTable.NumUntracked;
             if (NativeReader.ReadBits(image, 1, ref bitOffset) != 0)
             {
                 // RLE encoded
@@ -453,7 +453,7 @@ namespace R2RDump
                 bool fReport = true;
                 uint readSlots = NativeReader.DecodeVarLengthUnsigned(image, fSkip ? _gcInfoTypes.LIVESTATE_RLE_SKIP_ENCBASE : _gcInfoTypes.LIVESTATE_RLE_RUN_ENCBASE, ref bitOffset);
                 fSkip = !fSkip;
-                while (readSlots < numSlots)
+                while (readSlots < numTracked)
                 {
                     uint cnt = NativeReader.DecodeVarLengthUnsigned(image, fSkip ? _gcInfoTypes.LIVESTATE_RLE_SKIP_ENCBASE : _gcInfoTypes.LIVESTATE_RLE_RUN_ENCBASE, ref bitOffset) + 1;
                     if (fReport)
@@ -467,9 +467,9 @@ namespace R2RDump
             }
             else
             {
-                foreach (var slot in slots)
+                foreach (var slot in SlotTable.GcSlots)
                 {
-                    if (slot.StackSlot != null)
+                    if (slot.Flags == GcSlotFlags.GC_SLOT_UNTRACKED)
                         break;
 
                     if (NativeReader.ReadBits(image, 1, ref bitOffset) != 0)
index 6fd7909..b8e981f 100644 (file)
@@ -182,10 +182,6 @@ namespace R2RDump
         GC_SLOT_INTERIOR = 0x1,
         GC_SLOT_PINNED = 0x2,
         GC_SLOT_UNTRACKED = 0x4,
-
-        // For internal use by the encoder/decoder
-        GC_SLOT_IS_REGISTER = 0x8,
-        GC_SLOT_IS_DELETED = 0x10,
     };
 
     public enum GcStackSlotBase
index 750c65d..df2c310 100644 (file)
@@ -17,11 +17,18 @@ namespace R2RDump
             public GcStackSlot StackSlot { get; }
             public GcSlotFlags Flags { get; }
 
-            public GcSlot(int registerNumber, GcStackSlot stack, GcSlotFlags flags)
+            public GcSlot(int registerNumber, GcStackSlot stack, GcSlotFlags flags, bool isUntracked = false)
             {
                 RegisterNumber = registerNumber;
                 StackSlot = stack;
-                Flags = flags;
+                if (isUntracked)
+                {
+                    Flags = GcSlotFlags.GC_SLOT_UNTRACKED;
+                }
+                else
+                {
+                    Flags = flags;
+                }
             }
 
             public override string ToString()
@@ -70,11 +77,11 @@ namespace R2RDump
             }
             if ((NumStackSlots > 0) && (GcSlots.Count < gcInfoTypes.MAX_PREDECODED_SLOTS))
             {
-                DecodeStackSlots(image, machine, gcInfoTypes, NumStackSlots, ref bitOffset);
+                DecodeStackSlots(image, machine, gcInfoTypes, NumStackSlots, false, ref bitOffset);
             }
             if ((NumUntracked > 0) && (GcSlots.Count < gcInfoTypes.MAX_PREDECODED_SLOTS))
             {
-                DecodeStackSlots(image, machine, gcInfoTypes, NumUntracked, ref bitOffset);
+                DecodeStackSlots(image, machine, gcInfoTypes, NumUntracked, true, ref bitOffset);
             }
         }
 
@@ -119,14 +126,14 @@ namespace R2RDump
             }
         }
 
-        private void DecodeStackSlots(byte[] image, Machine machine, GcInfoTypes gcInfoTypes, uint nSlots, ref int bitOffset)
+        private void DecodeStackSlots(byte[] image, Machine machine, GcInfoTypes gcInfoTypes, uint nSlots, bool isUntracked, ref int bitOffset)
         {
             // We have stack slots left and more room to predecode
             GcStackSlotBase spBase = (GcStackSlotBase)NativeReader.ReadBits(image, 2, ref bitOffset);
             int normSpOffset = NativeReader.DecodeVarLengthSigned(image, gcInfoTypes.STACK_SLOT_ENCBASE, ref bitOffset);
             int spOffset = gcInfoTypes.DenormalizeStackSlot(normSpOffset);
             GcSlotFlags flags = (GcSlotFlags)NativeReader.ReadBits(image, 2, ref bitOffset);
-            GcSlots.Add(new GcSlot(-1, new GcStackSlot(spOffset, spBase), flags));
+            GcSlots.Add(new GcSlot(-1, new GcStackSlot(spOffset, spBase), flags, isUntracked));
 
             for (int i = 1; i < nSlots; i++)
             {
@@ -143,7 +150,7 @@ namespace R2RDump
                     normSpOffset += normSpOffsetDelta;
                     spOffset = gcInfoTypes.DenormalizeStackSlot(normSpOffset);
                 }
-                GcSlots.Add(new GcSlot(-1, new GcStackSlot(spOffset, spBase), flags));
+                GcSlots.Add(new GcSlot(-1, new GcStackSlot(spOffset, spBase), flags, isUntracked));
             }
         }
     }