-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathTypeData.cs
136 lines (117 loc) · 3.67 KB
/
TypeData.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
namespace UnityHeapDumper
{
public class TypeData : ITypeData
{
private Type type;
private int size;
private List<IFieldData> staticFields;
private List<FieldInfo> instanceFields;
private bool isPureValueType;
public void Init(IDumpContext dumpContext, Type type)
{
this.type = type;
size = 0;
var typeDataFactory = dumpContext.TypeDataFactory;
instanceFields = GetInstanceFields(typeDataFactory);
isPureValueType = IsPureValueType(typeDataFactory);
if (isPureValueType)
{
if (type.IsEnum)
{
Type uderlyingType = Enum.GetUnderlyingType(type);
size = Marshal.SizeOf(uderlyingType);
}
else
{
size = Marshal.SizeOf(type);
}
}
var fieldDataFactory = dumpContext.FieldDataFactory;
staticFields = GetStaticFields(fieldDataFactory);
}
private List<IFieldData> GetStaticFields(IFactory<IFieldData, FieldInfo, object> fieldDataFactory)
{
var staticFieldInfos = type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
var staticFields = new List<IFieldData>(staticFieldInfos.Length);
foreach (var fieldInfo in staticFieldInfos)
{
var fieldData = fieldDataFactory.Create(fieldInfo, null);
staticFields.Add(fieldData);
}
return staticFields;
}
private List<FieldInfo> GetInstanceFields(IFactory<ITypeData, Type> typeDataFactory)
{
var instanceFieldInfos = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
var instanceFields = new List<FieldInfo>(instanceFieldInfos.Length);
instanceFields.AddRange(instanceFieldInfos);
var baseType = type.BaseType;
if (baseType != null)
{
var baseTypeData = typeDataFactory.Create(baseType);
instanceFields.AddRange(baseTypeData.InstanceFields);
}
return instanceFields;
}
private bool IsPureValueType(IFactory<ITypeData, Type> typeDataFactory)
{
if (!type.IsValueType)
{
return false;
}
if (type.IsPrimitive)
{
return true;
}
foreach (var instanceField in instanceFields)
{
var fieldType = instanceField.FieldType;
var fieldTypeData = typeDataFactory.Create(fieldType);
if (!fieldTypeData.IsPureValueType)
{
return false;
}
}
return true;
}
Type ITypeData.Type
{
get
{
return type;
}
}
int ITypeData.Size
{
get
{
return size;
}
}
IList<IFieldData> ITypeData.StaticFields
{
get
{
return staticFields;
}
}
IList<FieldInfo> ITypeData.InstanceFields
{
get
{
return instanceFields;
}
}
bool ITypeData.IsPureValueType
{
get
{
return isPureValueType;
}
}
}
}