< prev index next >

test/hotspot/jtreg/runtime/cds/AOTMapReader.java

Print this page

  1 /*
  2  * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */

178     //  - klass: 'java/lang/String' 0x0000000800010290
179     static Pattern instanceObjKlassPattern = Pattern.compile("^ - klass: '([^']+)' 0x([0-9a-f]+)");
180 
181     //  - klass: {type array byte} 0x00000008000024c8
182     static Pattern typeArrayKlassPattern = Pattern.compile("^ - klass: [{]type array ([a-z]+)[}] 0x([0-9a-f]+)");
183 
184     //  - klass: 'java/lang/Object'[] 0x00000008000013e0
185     static Pattern objArrayKlassPattern = Pattern.compile("^ - klass: ('[^']+'(\\[\\])+) 0x([0-9a-f]+)");
186 
187     //  - fields (3 words):
188     static Pattern fieldsWordsPattern = Pattern.compile("^ - fields [(]([0-9]+) words[)]:$");
189 
190     // (one address)
191     //  - final 'key' 'Ljava/lang/Object;' @16 0x00000007ffc68260 java.lang.String
192     static Pattern oopFieldPattern1 = Pattern.compile(" - [^']* '([^']+)'.*@([0-9]+) 0x([0-9a-f]+) (.*)");
193 
194     // (two addresses)
195     //  - final 'key' 'Ljava/lang/Object;' @16 0x00000007ffc68260 (0xfff8d04c) java.lang.String
196     static Pattern oopFieldPattern2 = Pattern.compile(" - [^']* '([^']+)'.*@([0-9]+) 0x([0-9a-f]+) [(]0x([0-9a-f]+)[)] (.*)");
197 











198     // (injected module_entry)
199     //  - injected 'module_entry' 'J' @16 0 (0x0000000000000000)
200     static Pattern moduleEntryPattern = Pattern.compile("- injected 'module_entry' 'J' @[0-9]+[ ]+([0-9]+)");
201 
202     // -------------------------------------------------------------------------------
203     // Patterns for metaspace objects
204     // -------------------------------------------------------------------------------
205 
206     // 0x00000008000d1698: @@ Class             512 [Ljdk.internal.vm.FillerElement;
207     // 0x00000008000d18a0: @@ Class             520 java.lang.Cloneable
208     static Pattern classPattern = Pattern.compile("^0x([0-9a-f]+): @@ Class [ ]*([0-9]+) (.*)");
209 
210 
211     private static Matcher match(String line, Pattern pattern) {
212         Matcher m = pattern.matcher(line);
213         if (m.find()) {
214             return m;
215         } else {
216             return null;
217         }
218     }
219 
220     private static void parseHeapObject(String className, String oop, String narrowOop) throws IOException {
221         HeapObject heapObject = parseHeapObjectImpl(className, oop, narrowOop);
222         mapFile.add(heapObject);
223     }
224 


















































225     private static HeapObject parseHeapObjectImpl(String className, String oop, String narrowOop) throws IOException {
226         HeapObject heapObject = new HeapObject(className, oop, narrowOop);
227         Matcher m;
228 
229         nextLine();
230         while (line != null && match(line, rawDataPattern) != null) { // skip raw data
231             nextLine();
232         }
233 
234         if (line == null || !line.startsWith(" - ")) {
235             return heapObject;
236         }
237 
238         if ((m = match(line, instanceObjKlassPattern)) != null) {
239             heapObject.setKlass(m.group(1), m.group(2));
240             nextLine();
241             if ((m = match(line, fieldsWordsPattern)) == null) {
242                 throw new RuntimeException("Expected field size info");
243             }
244             while (true) {
245                 nextLine();
246                 if (line == null || !line.startsWith(" - ")) {
247                     return heapObject;
248                 }
249                 if (!line.contains("marked metadata pointer")) {
250                     if ((m = match(line, oopFieldPattern2)) != null) {
251                         heapObject.addOopField(m.group(1), m.group(2), m.group(3), m.group(4));
252                     } else if ((m = match(line, oopFieldPattern1)) != null) {
253                         heapObject.addOopField(m.group(1), m.group(2), m.group(3), null);







254                     } else if ((m = match(line, moduleEntryPattern)) != null) {
255                         String value = m.group(1);
256                         if (!value.equals("0")) {
257                             throw new RuntimeException("module_entry should be 0 but found: " + line);
258                         }
259                     }
260                 }
261             }
262         } else if ((m = match(line, typeArrayKlassPattern)) != null) {
263             heapObject.setKlass(m.group(1), m.group(2));
264             // TODO: read all the array elements
265             while (true) {
266                 nextLine();
267                 if (line == null || !line.startsWith(" - ")) {
268                     return heapObject;
269                 }
270             }
271         } else if ((m = match(line, objArrayKlassPattern)) != null) {
272             heapObject.setKlass(m.group(1), m.group(3));
273             // TODO: read all the array elements
274             while (true) {
275                 nextLine();
276                 if (line == null || !line.startsWith(" - ")) {
277                     return heapObject;
278                 }






279             }
280         } else {
281             throw new RuntimeException("Expected klass info");
282         }
283     }
284 
285     private static void parseClassObject(String className, String addr, String size) throws IOException {
286         mapFile.addClass(className);
287         nextLine();
288     }
289 
290     static MapFile mapFile;
291     static BufferedReader reader;
292     static String line = null; // current line being parsed
293     static int lineCount = 0;
294     static String nextLine()  throws IOException {
295         line = reader.readLine();
296         ++ lineCount;
297         return line;
298     }

  1 /*
  2  * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */

178     //  - klass: 'java/lang/String' 0x0000000800010290
179     static Pattern instanceObjKlassPattern = Pattern.compile("^ - klass: '([^']+)' 0x([0-9a-f]+)");
180 
181     //  - klass: {type array byte} 0x00000008000024c8
182     static Pattern typeArrayKlassPattern = Pattern.compile("^ - klass: [{]type array ([a-z]+)[}] 0x([0-9a-f]+)");
183 
184     //  - klass: 'java/lang/Object'[] 0x00000008000013e0
185     static Pattern objArrayKlassPattern = Pattern.compile("^ - klass: ('[^']+'(\\[\\])+) 0x([0-9a-f]+)");
186 
187     //  - fields (3 words):
188     static Pattern fieldsWordsPattern = Pattern.compile("^ - fields [(]([0-9]+) words[)]:$");
189 
190     // (one address)
191     //  - final 'key' 'Ljava/lang/Object;' @16 0x00000007ffc68260 java.lang.String
192     static Pattern oopFieldPattern1 = Pattern.compile(" - [^']* '([^']+)'.*@([0-9]+) 0x([0-9a-f]+) (.*)");
193 
194     // (two addresses)
195     //  - final 'key' 'Ljava/lang/Object;' @16 0x00000007ffc68260 (0xfff8d04c) java.lang.String
196     static Pattern oopFieldPattern2 = Pattern.compile(" - [^']* '([^']+)'.*@([0-9]+) 0x([0-9a-f]+) [(]0x([0-9a-f]+)[)] (.*)");
197 
198     // - Flat inline type element 'java/lang/Integer': - Index   1 offset  24:
199     // or
200     // - Flat inline type field 'java/lang/Integer':
201     static Pattern flatFieldPattern = Pattern.compile(" - Flat inline type field '([^']+)':\\s*(null)?\\s*$");
202     static Pattern flatElementPattern = Pattern.compile(" - Flat inline type element '([^']+)':\\s*- Index\\s+(\\d+)\\s+offset\\s+(\\d+):\\s*(null)?\\s*$");
203 
204     static Pattern flatNullFreeFieldPattern = Pattern.compile(" - Flat inline null-free type field '([^']+)':\\s*$");
205     static Pattern flatNullFreeElementPattern = Pattern.compile(" - Flat inline null-free type element '([^']+)':\\s*- Index\\s+(\\d+)\\s+offset\\s+(\\d+):\\s*$");
206 
207     static Pattern nullMarkerPattern = Pattern.compile(" - \\[null_marker\\] @[0-9]+ Field marked as (.*)");
208 
209     // (injected module_entry)
210     //  - injected 'module_entry' 'J' @16 0 (0x0000000000000000)
211     static Pattern moduleEntryPattern = Pattern.compile("- injected 'module_entry' 'J' @[0-9]+[ ]+([0-9]+)");
212 
213     // -------------------------------------------------------------------------------
214     // Patterns for metaspace objects
215     // -------------------------------------------------------------------------------
216 
217     // 0x00000008000d1698: @@ Class             512 [Ljdk.internal.vm.FillerElement;
218     // 0x00000008000d18a0: @@ Class             520 java.lang.Cloneable
219     static Pattern classPattern = Pattern.compile("^0x([0-9a-f]+): @@ Class [ ]*([0-9]+) (.*)");
220 
221 
222     private static Matcher match(String line, Pattern pattern) {
223         Matcher m = pattern.matcher(line);
224         if (m.find()) {
225             return m;
226         } else {
227             return null;
228         }
229     }
230 
231     private static void parseHeapObject(String className, String oop, String narrowOop) throws IOException {
232         HeapObject heapObject = parseHeapObjectImpl(className, oop, narrowOop);
233         mapFile.add(heapObject);
234     }
235 
236     private static void parseFlatNullFree(Matcher m) throws IOException {
237         if (line == null || !line.matches("^\s*-.*")) {
238             throw new RuntimeException("Malformed logging of flat field: " + line);
239         } else if ((m = match(line, flatFieldPattern)) != null) {
240             parseFlatField(m);
241         } else if ((m = match(line, flatElementPattern)) != null) {
242             parseFlatElement(m);
243         } else {
244             // Nested field
245         }
246     }
247 
248     private static void parseFlatFieldOrElementHelper(Matcher m, String value) throws IOException {
249         nextLine();
250         while (line == null || (m = match(line, nullMarkerPattern)) == null) {
251             parseFlatNullFree(m);
252             nextLine();
253         }
254 
255         String nullMarker = m.group(1);
256         if (nullMarker == null) {
257             throw new RuntimeException("missing null_marker: " + line);
258         } else {
259             nullMarker = nullMarker.replace(" ", "");
260             if (value.equals("null") != nullMarker.equals("null")) {
261                 throw new RuntimeException("Incorrect null_marker value: " + value + " vs " + nullMarker);
262             }
263         }
264     }
265 
266     private static void parseFlatElement(Matcher m) throws IOException {
267         String value = m.group(4);
268         if (value != null) {
269             value = value.replace(" ", ""); // Remove spaces
270         } else {
271             value = "";
272         }
273         parseFlatFieldOrElementHelper(m, value);
274     }
275 
276     private static void parseFlatField(Matcher m) throws IOException {
277         String value = m.group(2);
278         if (value != null) {
279             value = value.replace(" ", ""); // Remove spaces
280         } else {
281             value = "";
282         }
283         parseFlatFieldOrElementHelper(m, value);
284     }
285 
286     private static HeapObject parseHeapObjectImpl(String className, String oop, String narrowOop) throws IOException {
287         HeapObject heapObject = new HeapObject(className, oop, narrowOop);
288         Matcher m;
289 
290         nextLine();
291         while (line != null && match(line, rawDataPattern) != null) { // skip raw data
292             nextLine();
293         }
294 
295         if (line == null || !line.startsWith(" - ")) {
296             return heapObject;
297         }
298 
299         if ((m = match(line, instanceObjKlassPattern)) != null) {
300             heapObject.setKlass(m.group(1), m.group(2));
301             nextLine();
302             if ((m = match(line, fieldsWordsPattern)) == null) {
303                 throw new RuntimeException("Expected field size info");
304             }
305             while (true) {
306                 nextLine();
307                 if (line == null || !line.matches("^\s*-.*")) {
308                     return heapObject;
309                 }
310                 if (!line.contains("marked metadata pointer")) {
311                     if ((m = match(line, oopFieldPattern2)) != null) {
312                         heapObject.addOopField(m.group(1), m.group(2), m.group(3), m.group(4));
313                     } else if ((m = match(line, oopFieldPattern1)) != null) {
314                         heapObject.addOopField(m.group(1), m.group(2), m.group(3), null);
315                     } else if ((m = match(line, flatFieldPattern)) != null) {
316                         parseFlatField(m);
317                     } else if ((m = match(line, flatElementPattern)) != null) {
318                         parseFlatElement(m);
319                     } else if ((m = match(line, flatNullFreeFieldPattern)) != null ||
320                                (m = match(line, flatNullFreeElementPattern)) != null) {
321                         parseFlatNullFree(m);
322                     } else if ((m = match(line, moduleEntryPattern)) != null) {
323                         String value = m.group(1);
324                         if (!value.equals("0")) {
325                             throw new RuntimeException("module_entry should be 0 but found: " + line);
326                         }
327                     }
328                 }
329             }
330         } else if ((m = match(line, typeArrayKlassPattern)) != null) {
331             heapObject.setKlass(m.group(1), m.group(2));
332             // TODO: read all the array elements
333             while (true) {
334                 nextLine();
335                 if (line == null || !line.startsWith(" - ")) {
336                     return heapObject;
337                 }
338             }
339         } else if ((m = match(line, objArrayKlassPattern)) != null) {
340             heapObject.setKlass(m.group(1), m.group(3));
341             // TODO: read all the array elements
342             while (true) {
343                 nextLine();
344                 if (line == null || !line.matches("^\s*-.*")) { // Check for "-" with leading spaces
345                     return heapObject;
346                 }
347 
348                 if ((m = match(line, flatElementPattern)) != null) {
349                     parseFlatElement(m);
350                 } else if ((m = match(line, flatNullFreeElementPattern)) != null) {
351                     parseFlatNullFree(m);
352                 }
353             }
354         } else {
355             throw new RuntimeException("Expected klass info");
356         }
357     }
358 
359     private static void parseClassObject(String className, String addr, String size) throws IOException {
360         mapFile.addClass(className);
361         nextLine();
362     }
363 
364     static MapFile mapFile;
365     static BufferedReader reader;
366     static String line = null; // current line being parsed
367     static int lineCount = 0;
368     static String nextLine()  throws IOException {
369         line = reader.readLine();
370         ++ lineCount;
371         return line;
372     }
< prev index next >