Skip to content

Commit

Permalink
Remove legacy runtime support (#342)
Browse files Browse the repository at this point in the history
* Merge all ClrHeap subclasses

- Merged all ClrHeap subclasses into one.

* Remove legacy runtime support

- Only support .Net Core and Desktop CLR 4.6+.

* Fix bad exception in version check
  • Loading branch information
leculver committed Nov 25, 2019
1 parent 937d901 commit a385ae4
Show file tree
Hide file tree
Showing 28 changed files with 490 additions and 2,223 deletions.
6 changes: 3 additions & 3 deletions src/Microsoft.Diagnostics.Runtime.Tests/src/GCRootTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,14 @@ public void ObjectSetAddRemove()
ClrHeap heap = runtime.Heap;

ObjectSet hash = new ObjectSet(heap);
foreach (ulong obj in heap.EnumerateObjectAddresses())
foreach (ulong obj in heap.EnumerateObjects())
{
Assert.False(hash.Contains(obj));
hash.Add(obj);
Assert.True(hash.Contains(obj));
}

foreach (ulong obj in heap.EnumerateObjectAddresses())
foreach (ulong obj in heap.EnumerateObjects())
{
Assert.True(hash.Contains(obj));
hash.Remove(obj);
Expand All @@ -92,7 +92,7 @@ public void ObjectSetTryAdd()
ClrHeap heap = runtime.Heap;

ObjectSet hash = new ObjectSet(heap);
foreach (ulong obj in heap.EnumerateObjectAddresses())
foreach (ulong obj in heap.EnumerateObjects())
{
Assert.False(hash.Contains(obj));
Assert.True(hash.Add(obj));
Expand Down
25 changes: 1 addition & 24 deletions src/Microsoft.Diagnostics.Runtime.Tests/src/HeapTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public void HeapEnumeration()

bool encounteredFoo = false;
int count = 0;
foreach (ulong obj in heap.EnumerateObjectAddresses())
foreach (ClrObject obj in heap.EnumerateObjects())
{
ClrType type = heap.GetObjectType(obj);
Assert.NotNull(type);
Expand All @@ -35,29 +35,6 @@ public void HeapEnumeration()
Assert.True(count > 0);
}

[Fact]
public void HeapEnumerationMatches()
{
// Simply test that we can enumerate the heap.
using DataTarget dt = TestTargets.Types.LoadFullDump();
ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime();
ClrHeap heap = runtime.Heap;

List<ClrObject> objects = new List<ClrObject>(heap.EnumerateObjects());

int count = 0;
foreach (ulong obj in heap.EnumerateObjectAddresses())
{
ClrObject actual = objects[count++];

Assert.Equal(obj, actual.Address);

ClrType type = heap.GetObjectType(obj);
Assert.Equal(type, actual.Type);
}

Assert.True(count > 0);
}

[Fact]
public void HeapCachedEnumerationMatches()
Expand Down
7 changes: 3 additions & 4 deletions src/Microsoft.Diagnostics.Runtime.Tests/src/Helpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@ public static class Helpers
{
public static IEnumerable<ulong> GetObjectsOfType(this ClrHeap heap, string name)
{
return from obj in heap.EnumerateObjectAddresses()
let type = heap.GetObjectType(obj)
where type?.Name == name
select obj;
return from obj in heap.EnumerateObjects()
where obj.Type?.Name == name
select obj.Address;
}

public static ClrObject GetStaticObjectValue(this ClrType mainType, string fieldName)
Expand Down
35 changes: 16 additions & 19 deletions src/Microsoft.Diagnostics.Runtime.Tests/src/TypeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public void IntegerObjectClrType()
Assert.IsType<int>(value);
Assert.Equal(42, (int)value);

Assert.Contains(addr, heap.EnumerateObjectAddresses());
Assert.Contains(addr, heap.EnumerateObjects().Select(a => a.Address));
}

[FrameworkFact]
Expand All @@ -50,15 +50,14 @@ public void ArrayComponentTypeTest()
ClrHeap heap = runtime.Heap;

// Ensure that we always have a component for every array type.
foreach (ulong obj in heap.EnumerateObjectAddresses())
foreach (ClrObject obj in heap.EnumerateObjects())
{
ClrType type = heap.GetObjectType(obj);
ClrType type = obj.Type;
Assert.True(!type.IsArray || type.ComponentType != null);

foreach (ClrInstanceField field in type.Fields)
{
Assert.NotNull(field.Type);
Assert.True(!field.Type.IsArray || field.Type.ComponentType != null);
Assert.Same(heap, field.Type.Heap);
}
}
Expand All @@ -82,9 +81,9 @@ public void ComponentType()
ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime();
ClrHeap heap = runtime.Heap;

foreach (ulong obj in heap.EnumerateObjectAddresses())
foreach (ClrObject obj in heap.EnumerateObjects())
{
ClrType type = heap.GetObjectType(obj);
ClrType type = obj.Type;
Assert.NotNull(type);

if (type.IsArray || type.IsPointer)
Expand All @@ -105,8 +104,8 @@ public void TypeEqualityTest()
ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime();
ClrHeap heap = runtime.Heap;

ClrType[] types = (from obj in heap.EnumerateObjectAddresses()
let t = heap.GetObjectType(obj)
ClrType[] types = (from obj in heap.EnumerateObjects()
let t = heap.GetObjectType(obj.Address)
where t.Name == TypeName
select t).ToArray();

Expand Down Expand Up @@ -165,9 +164,8 @@ public void EETypeTest()
ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime();
ClrHeap heap = runtime.Heap;

HashSet<ulong> methodTables = (from obj in heap.EnumerateObjectAddresses()
let type = heap.GetObjectType(obj)
where !type.IsFree
HashSet<ulong> methodTables = (from obj in heap.EnumerateObjects()
where !obj.Type.IsFree
select heap.GetMethodTable(obj)).Unique();

Assert.DoesNotContain(0ul, methodTables);
Expand All @@ -189,7 +187,7 @@ public void MethodTableHeapEnumeration()
ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime();
ClrHeap heap = runtime.Heap;

foreach (ClrType type in heap.EnumerateObjectAddresses().Select(obj => heap.GetObjectType(obj)).Unique())
foreach (ClrType type in heap.EnumerateObjects().Select(obj => heap.GetObjectType(obj.Address)).Unique())
{
Assert.NotEqual(0ul, type.MethodTable);

Expand Down Expand Up @@ -220,10 +218,10 @@ public void GetObjectMethodTableTest()
ClrHeap heap = runtime.Heap;

int i = 0;
foreach (ulong obj in heap.EnumerateObjectAddresses())
foreach (ClrObject obj in heap.EnumerateObjects())
{
i++;
ClrType type = heap.GetObjectType(obj);
ClrType type = obj.Type;

if (type.IsArray)
{
Expand Down Expand Up @@ -262,10 +260,9 @@ public void EnumerateMethodTableTest()
ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime();
ClrHeap heap = runtime.Heap;

ulong[] fooObjects = (from obj in heap.EnumerateObjectAddresses()
let t = heap.GetObjectType(obj)
where t.Name == "Foo"
select obj).ToArray();
ulong[] fooObjects = (from obj in heap.EnumerateObjects()
where obj.Type.Name == "Foo"
select obj.Address).ToArray();

// There are exactly two Foo objects in the process, one in each app domain.
// They will have different method tables.
Expand Down Expand Up @@ -353,7 +350,7 @@ public void CollectibleTypeTest()

ClrHeap heap = dataTarget.ClrVersions.Single().CreateRuntime().Heap;

ClrType[] types = heap.EnumerateObjectAddresses().Select(addr => heap.GetObjectType(addr)).ToArray();
ClrType[] types = heap.EnumerateObjects().Select(obj => obj.Type).ToArray();

ClrType collectibleType = types.Single(type => type?.Name == typeof(CollectibleUnmanagedStruct).FullName);

Expand Down
8 changes: 0 additions & 8 deletions src/Microsoft.Diagnostics.Runtime/src/Common/ClrHeap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -248,14 +248,6 @@ public virtual IEnumerable<ulong> EnumerateFinalizableObjectAddresses()
/// </summary>
public abstract bool CanWalkHeap { get; }

/// <summary>
/// Enumerates all objects on the heap. This is equivalent to enumerating all segments then walking
/// each object with ClrSegment.FirstObject, ClrSegment.NextObject, but in a simple enumerator
/// for easier use in linq queries.
/// </summary>
/// <returns>An enumerator for all objects on the heap.</returns>
public abstract IEnumerable<ulong> EnumerateObjectAddresses();

/// <summary>
/// Enumerates all objects on the heap.
/// </summary>
Expand Down
28 changes: 0 additions & 28 deletions src/Microsoft.Diagnostics.Runtime/src/Common/ClrRuntime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,34 +181,6 @@ protected void OnRuntimeFlushed()
RuntimeFlushed?.Invoke(this);
}

/// <summary>
/// Whether or not the runtime has component method tables for arrays. This is an extra field in
/// array objects on the heap, which was removed in v4.6 of desktop clr.
/// </summary>
internal bool HasArrayComponentMethodTables
{
get
{
if (ClrInfo.Flavor == ClrFlavor.Desktop)
{
VersionInfo version = ClrInfo.Version;
if (version.Major > 4)
return false;

if (version.Major == 4 && version.Minor >= 6)
return false;
}
else if (ClrInfo.Flavor == ClrFlavor.Core)
{
return false;
}

return true;
}
}



internal void Dispose()
{
DacLibrary?.Dispose();
Expand Down
Loading

0 comments on commit a385ae4

Please sign in to comment.