24
24
*/
25
25
package com .oracle .svm .core .heap .dump ;
26
26
27
+ import java .util .EnumSet ;
28
+
27
29
import org .graalvm .nativeimage .ImageSingletons ;
28
30
import org .graalvm .nativeimage .Platform ;
29
31
import org .graalvm .nativeimage .Platforms ;
44
46
import com .oracle .svm .core .heap .ObjectVisitor ;
45
47
import com .oracle .svm .core .heap .UnknownObjectField ;
46
48
import com .oracle .svm .core .hub .DynamicHub ;
49
+ import com .oracle .svm .core .layeredimagesingleton .InitialLayerOnlyImageSingleton ;
50
+ import com .oracle .svm .core .layeredimagesingleton .LayeredImageSingletonBuilderFlags ;
51
+ import com .oracle .svm .core .layeredimagesingleton .LayeredImageSingletonSupport ;
52
+ import com .oracle .svm .core .layeredimagesingleton .MultiLayeredImageSingleton ;
53
+ import com .oracle .svm .core .layeredimagesingleton .UnsavedSingleton ;
47
54
import com .oracle .svm .core .memory .NullableNativeMemory ;
48
55
import com .oracle .svm .core .nmt .NmtCategory ;
49
56
import com .oracle .svm .core .util .coder .ByteStream ;
50
57
import com .oracle .svm .core .util .coder .ByteStreamAccess ;
51
58
import com .oracle .svm .core .util .coder .NativeCoder ;
52
59
import com .oracle .svm .core .util .coder .Pack200Coder ;
53
60
54
- import jdk .graal .compiler .api .replacements .Fold ;
55
61
import jdk .graal .compiler .word .Word ;
56
62
57
63
/**
95
101
* |----------------------------|
96
102
* </pre>
97
103
*/
98
- public class HeapDumpMetadata {
104
+ public class HeapDumpMetadata implements InitialLayerOnlyImageSingleton {
99
105
private final ComputeHubDataVisitor computeHubDataVisitor ;
100
- @ UnknownObjectField (availability = AfterCompilation .class ) private byte [] data ;
101
106
102
107
private int fieldNameCount ;
103
108
private int classInfoCount ;
@@ -110,30 +115,37 @@ public HeapDumpMetadata() {
110
115
computeHubDataVisitor = new ComputeHubDataVisitor ();
111
116
}
112
117
113
- @ Fold
114
118
public static HeapDumpMetadata singleton () {
115
119
return ImageSingletons .lookup (HeapDumpMetadata .class );
116
120
}
117
121
118
- @ Platforms (Platform .HOSTED_ONLY .class )
119
- public void setData (byte [] value ) {
120
- this .data = value ;
121
- }
122
-
123
122
public boolean initialize () {
124
123
assert classInfos .isNull () && fieldInfoTable .isNull () && fieldNameTable .isNull ();
125
124
126
- Pointer start = NonmovableArrays .getArrayBase (NonmovableArrays .fromImageHeap (data ));
127
- Pointer end = start .add (data .length );
125
+ HeapDumpEncodedData [] encodedDataArray = HeapDumpEncodedData .layeredSingletons ();
128
126
129
127
ByteStream stream = StackValue .get (ByteStream .class );
130
- ByteStreamAccess .initialize (stream , start );
131
128
132
- /* Read the header. */
133
- int totalFieldCount = NativeCoder .readInt (stream );
134
- int classCount = NativeCoder .readInt (stream );
135
- fieldNameCount = NativeCoder .readInt (stream );
136
- int maxTypeId = Pack200Coder .readUVAsInt (stream );
129
+ int totalFieldCount = 0 ;
130
+ int totalFieldNameCount = 0 ;
131
+ int maxTypeId = Integer .MIN_VALUE ;
132
+
133
+ /*
134
+ * First read all encoded data arrays to determine how large of data structures to allocate.
135
+ */
136
+ for (HeapDumpEncodedData encodedData : encodedDataArray ) {
137
+ byte [] data = encodedData .data ;
138
+
139
+ Pointer start = NonmovableArrays .getArrayBase (NonmovableArrays .fromImageHeap (data ));
140
+ ByteStreamAccess .initialize (stream , start );
141
+
142
+ /* Read the header. */
143
+ totalFieldCount += NativeCoder .readInt (stream );
144
+ NativeCoder .readInt (stream ); // class count
145
+ totalFieldNameCount += NativeCoder .readInt (stream );
146
+ maxTypeId = Integer .max (Pack200Coder .readUVAsInt (stream ), maxTypeId );
147
+ }
148
+ fieldNameCount = totalFieldNameCount ;
137
149
classInfoCount = maxTypeId + 1 ;
138
150
139
151
/*
@@ -159,45 +171,65 @@ public boolean initialize() {
159
171
return false ;
160
172
}
161
173
162
- /* Read the classes and fields. */
163
- int fieldIndex = 0 ;
164
- for (int i = 0 ; i < classCount ; i ++) {
165
- int typeId = Pack200Coder .readUVAsInt (stream );
166
-
167
- ClassInfo classInfo = getClassInfo (typeId );
168
-
169
- int numInstanceFields = Pack200Coder .readUVAsInt (stream );
170
- classInfo .setInstanceFieldCount (numInstanceFields );
171
-
172
- int numStaticFields = Pack200Coder .readUVAsInt (stream );
173
- classInfo .setStaticFieldCount (numStaticFields );
174
-
175
- classInfo .setInstanceFields (fieldInfoTable .addressOf (fieldIndex ));
176
- for (int j = 0 ; j < numInstanceFields ; j ++) {
177
- Pointer fieldInfo = (Pointer ) fieldInfoTable .addressOf (fieldIndex );
178
- fieldInfo .writeWord (0 , stream .getPosition ());
179
- FieldInfoAccess .skipFieldInfo (stream );
180
- fieldIndex ++;
174
+ /*
175
+ * Next write the metadata from all data arrays into the data structures.
176
+ */
177
+ int fieldNameTableStartIdx = 0 ;
178
+ for (HeapDumpEncodedData encodedData : encodedDataArray ) {
179
+ byte [] data = encodedData .data ;
180
+
181
+ /* Re-initialize the stream. */
182
+ Pointer start = NonmovableArrays .getArrayBase (NonmovableArrays .fromImageHeap (data ));
183
+ ByteStreamAccess .initialize (stream , start );
184
+
185
+ /* Re-read the header. */
186
+ NativeCoder .readInt (stream ); // field count
187
+ int classCount = NativeCoder .readInt (stream );
188
+ int currentFieldNameCount = NativeCoder .readInt (stream );
189
+ Pack200Coder .readUVAsInt (stream ); // maxTypeId
190
+
191
+ /* Read the classes and fields. */
192
+ int fieldIndex = 0 ;
193
+ for (int i = 0 ; i < classCount ; i ++) {
194
+ int typeId = Pack200Coder .readUVAsInt (stream );
195
+
196
+ ClassInfo classInfo = getClassInfo (typeId );
197
+
198
+ int numInstanceFields = Pack200Coder .readUVAsInt (stream );
199
+ classInfo .setInstanceFieldCount (numInstanceFields );
200
+
201
+ int numStaticFields = Pack200Coder .readUVAsInt (stream );
202
+ classInfo .setStaticFieldCount (numStaticFields );
203
+
204
+ classInfo .setInstanceFields (fieldInfoTable .addressOf (fieldIndex ));
205
+ for (int j = 0 ; j < numInstanceFields ; j ++) {
206
+ Pointer fieldInfo = (Pointer ) fieldInfoTable .addressOf (fieldIndex );
207
+ fieldInfo .writeWord (0 , stream .getPosition ());
208
+ FieldInfoAccess .skipFieldInfo (stream );
209
+ fieldIndex ++;
210
+ }
211
+
212
+ classInfo .setStaticFields (fieldInfoTable .addressOf (fieldIndex ));
213
+ for (int j = 0 ; j < numStaticFields ; j ++) {
214
+ Pointer fieldInfo = (Pointer ) fieldInfoTable .addressOf (fieldIndex );
215
+ fieldInfo .writeWord (0 , stream .getPosition ());
216
+ FieldInfoAccess .skipFieldInfo (stream );
217
+ fieldIndex ++;
218
+ }
181
219
}
182
220
183
- classInfo . setStaticFields ( fieldInfoTable . addressOf ( fieldIndex ));
184
- for (int j = 0 ; j < numStaticFields ; j ++) {
185
- Pointer fieldInfo = (Pointer ) fieldInfoTable .addressOf (fieldIndex );
186
- fieldInfo .writeWord (0 , stream .getPosition ());
187
- FieldInfoAccess . skipFieldInfo (stream );
188
- fieldIndex ++ ;
221
+ /* Fill the symbol table. */
222
+ for (int i = fieldNameTableStartIdx ; i < currentFieldNameCount + fieldNameTableStartIdx ; i ++) {
223
+ Pointer fieldName = (Pointer ) fieldNameTable .addressOf (i );
224
+ fieldName .writeWord (0 , stream .getPosition ());
225
+ int length = Pack200Coder . readUVAsInt (stream );
226
+ stream . setPosition ( stream . getPosition (). add ( length )) ;
189
227
}
228
+ fieldNameTableStartIdx += currentFieldNameCount ;
229
+ Pointer end = start .add (data .length );
230
+ assert stream .getPosition ().equal (end );
190
231
}
191
232
192
- /* Fill the symbol table. */
193
- for (int i = 0 ; i < fieldNameCount ; i ++) {
194
- Pointer fieldName = (Pointer ) fieldNameTable .addressOf (i );
195
- fieldName .writeWord (0 , stream .getPosition ());
196
- int length = Pack200Coder .readUVAsInt (stream );
197
- stream .setPosition (stream .getPosition ().add (length ));
198
- }
199
- assert stream .getPosition ().equal (end );
200
-
201
233
/* Store the DynamicHubs in their corresponding ClassInfo structs. */
202
234
computeHubDataVisitor .initialize ();
203
235
Heap .getHeap ().walkImageHeapObjects (computeHubDataVisitor );
@@ -290,6 +322,16 @@ static int computeFieldsDumpSize(FieldInfoPointer fields, int fieldCount) {
290
322
return result ;
291
323
}
292
324
325
+ @ Override
326
+ public boolean accessibleInFutureLayers () {
327
+ return true ;
328
+ }
329
+
330
+ @ Override
331
+ public EnumSet <LayeredImageSingletonBuilderFlags > getImageBuilderFlags () {
332
+ return LayeredImageSingletonBuilderFlags .RUNTIME_ACCESS_ONLY ;
333
+ }
334
+
293
335
@ RawStructure
294
336
public interface ClassInfo extends PointerBase {
295
337
@ RawField
@@ -444,4 +486,26 @@ public void visitObject(Object o) {
444
486
}
445
487
}
446
488
}
489
+
490
+ public static class HeapDumpEncodedData implements MultiLayeredImageSingleton , UnsavedSingleton {
491
+ @ UnknownObjectField (availability = AfterCompilation .class ) private byte [] data ;
492
+
493
+ @ Override
494
+ public EnumSet <LayeredImageSingletonBuilderFlags > getImageBuilderFlags () {
495
+ return LayeredImageSingletonBuilderFlags .ALL_ACCESS ;
496
+ }
497
+
498
+ private static HeapDumpEncodedData currentLayer () {
499
+ return LayeredImageSingletonSupport .singleton ().lookup (HeapDumpEncodedData .class , false , true );
500
+ }
501
+
502
+ private static HeapDumpEncodedData [] layeredSingletons () {
503
+ return MultiLayeredImageSingleton .getAllLayers (HeapDumpEncodedData .class );
504
+ }
505
+
506
+ @ Platforms (Platform .HOSTED_ONLY .class )
507
+ public static void setData (byte [] value ) {
508
+ HeapDumpEncodedData .currentLayer ().data = value ;
509
+ }
510
+ }
447
511
}
0 commit comments