12
12
using System . Reflection . PortableExecutable ;
13
13
14
14
using Internal . TypeSystem ;
15
+ using Internal . TypeSystem . Ecma ;
15
16
16
17
using ILCompiler . DependencyAnalysis ;
17
18
using ILCompiler . DependencyAnalysisFramework ;
18
19
20
+ using Debug = System . Diagnostics . Debug ;
19
21
using ObjectData = ILCompiler . DependencyAnalysis . ObjectNode . ObjectData ;
20
22
using AssemblyName = System . Reflection . AssemblyName ;
21
23
@@ -24,12 +26,15 @@ namespace ILCompiler
24
26
public class MstatObjectDumper : ObjectDumper
25
27
{
26
28
private const int VersionMajor = 2 ;
27
- private const int VersionMinor = 0 ;
29
+ private const int VersionMinor = 1 ;
28
30
29
31
private readonly string _fileName ;
30
32
private readonly MstatEmitter _emitter ;
31
33
32
34
private readonly InstructionEncoder _types = new InstructionEncoder ( new BlobBuilder ( ) ) ;
35
+ private readonly InstructionEncoder _fieldRvas = new InstructionEncoder ( new BlobBuilder ( ) ) ;
36
+ private readonly InstructionEncoder _frozenObjects = new InstructionEncoder ( new BlobBuilder ( ) ) ;
37
+ private readonly InstructionEncoder _manifestResources = new InstructionEncoder ( new BlobBuilder ( ) ) ;
33
38
34
39
private readonly BlobBuilder _mangledNames = new BlobBuilder ( ) ;
35
40
@@ -71,7 +76,29 @@ protected override void DumpObjectNode(NodeFactory factory, ObjectNode node, Obj
71
76
case MethodExceptionHandlingInfoNode ehInfoNode :
72
77
_methodEhInfo . Add ( ehInfoNode . Method , objectData . Data . Length ) ;
73
78
break ;
79
+ case FieldRvaDataNode rvaDataNode :
80
+ _fieldRvas . OpCode ( ILOpCode . Ldtoken ) ;
81
+ _fieldRvas . Token ( _emitter . EmitMetadataHandleForTypeSystemEntity ( rvaDataNode . Field ) ) ;
82
+ _fieldRvas . LoadConstantI4 ( rvaDataNode . Field . GetFieldRvaData ( ) . Length ) ;
83
+ _fieldRvas . LoadConstantI4 ( AppendMangledName ( DependencyNodeCore < NodeFactory > . GetNodeName ( node , factory ) ) ) ;
84
+ // Breakdown of RVA data was introduced in MSTAT 2.1. Readers of 2.0 should still see it in the
85
+ // global blobs section. We can remove it from there in 3.0.
86
+ if ( VersionMajor == 2 )
87
+ goto reportAsBlob ;
88
+ case ArrayOfFrozenObjectsNode :
89
+ DumpFrozenRegion ( factory ) ;
90
+ // Breakdown of frozen regions was introduced in MSTAT 2.1. Readers of 2.0 should still see it in the
91
+ // global blobs section. We can remove it from there in 3.0.
92
+ if ( VersionMajor == 2 )
93
+ goto reportAsBlob ;
94
+ case ResourceDataNode resourceData :
95
+ DumpResourceData ( factory , resourceData ) ;
96
+ // Breakdown of resource data was introduced in MSTAT 2.1. Readers of 2.0 should still see it in the
97
+ // global blobs section. We can remove it from there in 3.0.
98
+ if ( VersionMajor == 2 )
99
+ goto reportAsBlob ;
74
100
default :
101
+ reportAsBlob :
75
102
string nodeName = GetObjectNodeName ( node ) ;
76
103
if ( ! _blobs . TryGetValue ( nodeName , out int size ) )
77
104
size = 0 ;
@@ -80,6 +107,41 @@ protected override void DumpObjectNode(NodeFactory factory, ObjectNode node, Obj
80
107
}
81
108
}
82
109
110
+ private void DumpFrozenRegion ( NodeFactory factory )
111
+ {
112
+ Debug . Assert ( _frozenObjects . Offset == 0 ) ;
113
+
114
+ foreach ( FrozenObjectNode frozenObject in factory . MetadataManager . GetFrozenObjects ( ) )
115
+ {
116
+ _frozenObjects . OpCode ( ILOpCode . Ldtoken ) ;
117
+ _frozenObjects . Token ( _emitter . EmitMetadataHandleForTypeSystemEntity ( frozenObject . ObjectType ) ) ;
118
+ _frozenObjects . LoadConstantI4 ( frozenObject . Size ) ;
119
+ _frozenObjects . LoadConstantI4 ( AppendMangledName ( DependencyNodeCore < NodeFactory > . GetNodeName ( frozenObject , factory ) ) ) ;
120
+
121
+ if ( frozenObject is SerializedFrozenObjectNode serObj )
122
+ {
123
+ _frozenObjects . OpCode ( ILOpCode . Ldtoken ) ;
124
+ _frozenObjects . Token ( _emitter . EmitMetadataHandleForTypeSystemEntity ( serObj . OwningType ) ) ;
125
+ }
126
+ else
127
+ {
128
+ _frozenObjects . LoadConstantI4 ( 0 ) ;
129
+ }
130
+ }
131
+ }
132
+
133
+ private void DumpResourceData ( NodeFactory factory , ResourceDataNode resourceData )
134
+ {
135
+ Debug . Assert ( _manifestResources . Offset == 0 ) ;
136
+
137
+ foreach ( ResourceIndexData resource in resourceData . GetOrCreateIndexData ( factory ) )
138
+ {
139
+ _manifestResources . LoadConstantI4 ( MetadataTokens . GetToken ( _emitter . GetAssemblyRef ( resource . Assembly ) ) ) ;
140
+ _manifestResources . LoadString ( _emitter . GetUserStringHandle ( resource . ResourceName ) ) ;
141
+ _manifestResources . LoadConstantI4 ( resource . Length ) ;
142
+ }
143
+ }
144
+
83
145
private int AppendMangledName ( string mangledName )
84
146
{
85
147
int index = _mangledNames . Count ;
@@ -110,6 +172,9 @@ internal override void End()
110
172
_emitter . AddGlobalMethod ( "Methods" , methods , 0 ) ;
111
173
_emitter . AddGlobalMethod ( "Types" , _types , 0 ) ;
112
174
_emitter . AddGlobalMethod ( "Blobs" , blobs , 0 ) ;
175
+ _emitter . AddGlobalMethod ( "RvaFields" , _fieldRvas , 0 ) ;
176
+ _emitter . AddGlobalMethod ( "FrozenObjects" , _frozenObjects , 0 ) ;
177
+ _emitter . AddGlobalMethod ( "ManifestResources" , _manifestResources , 0 ) ;
113
178
114
179
_emitter . AddPESection ( ".names" , _mangledNames ) ;
115
180
0 commit comments