@@ -72,7 +72,7 @@ public abstract class DebugInfoBase {
7272 *
7373 * An alternative traversal option is
7474 *
75- * 1) by top level class (String id)
75+ * 1) by top level class (unique ResolvedJavaType id)
7676 *
7777 * 2) by top level compiled method (primary Range) within a class ordered by ascending address
7878 *
@@ -83,6 +83,18 @@ public abstract class DebugInfoBase {
8383 * means we can treat each class as a compilation unit, allowing data common to all methods of
8484 * the class to be shared.
8585 *
86+ * Just as an aside, for full disclosure, this is not strictly the full story. Sometimes a class
87+ * can include speculatively optimized, compiled methods plus deopt fallback compiled variants
88+ * of those same methods. In such cases the normal and/or speculatively compiled methods occupy
89+ * one contiguous range and deopt methods occupy a separate higher range. The current
90+ * compilation strategy ensures that the union across all classes of the normal/speculative
91+ * ranges and the union across all classes of the deopt ranges lie in two distinct intervals
92+ * where the highest address in the first union is strictly less than the lowest address in the
93+ * second union. The implication is twofold. An address order traversal requires generating
94+ * details for classes, methods and non-deopt primary ranges before generating details for the
95+ * deopt primary ranges. The former details need to be generated in a distinct CU from deopt
96+ * method details.
97+ *
8698 * A third option appears to be to traverse via files, then top level class within file etc.
8799 * Unfortunately, files cannot be treated as the compilation unit. A file F may contain multiple
88100 * classes, say C1 and C2. There is no guarantee that methods for some other class C' in file F'
@@ -96,17 +108,22 @@ public abstract class DebugInfoBase {
96108 */
97109 private List <TypeEntry > types = new ArrayList <>();
98110 /**
99- * index of already seen classes.
111+ * Index of already seen classes keyed by the unique, associated, identifying ResolvedJavaType
112+ * or, in the single special case of the TypeEntry for the Java header structure, by key null.
100113 */
101- private Map <String , TypeEntry > typesIndex = new HashMap <>();
114+ private Map <ResolvedJavaType , TypeEntry > typesIndex = new HashMap <>();
102115 /**
103116 * List of class entries detailing class info for primary ranges.
104117 */
105118 private List <ClassEntry > primaryClasses = new ArrayList <>();
106119 /**
107- * index of already seen classes.
120+ * Index of already seen classes.
108121 */
109122 private Map <ResolvedJavaType , ClassEntry > primaryClassesIndex = new HashMap <>();
123+ /**
124+ * Handle on class entry for java.lang.Object.
125+ */
126+ private ClassEntry objectClass ;
110127 /**
111128 * Index of files which contain primary or secondary ranges.
112129 */
@@ -213,7 +230,8 @@ public void installDebugInfo(DebugInfoProvider debugInfoProvider) {
213230
214231 /* Create all the types. */
215232 debugInfoProvider .typeInfoProvider ().forEach (debugTypeInfo -> debugTypeInfo .debugContext ((debugContext ) -> {
216- String typeName = TypeEntry .canonicalize (debugTypeInfo .typeName ());
233+ ResolvedJavaType idType = debugTypeInfo .idType ();
234+ String typeName = debugTypeInfo .typeName ();
217235 typeName = stringTable .uniqueDebugString (typeName );
218236 DebugTypeKind typeKind = debugTypeInfo .typeKind ();
219237 int byteSize = debugTypeInfo .size ();
@@ -222,16 +240,17 @@ public void installDebugInfo(DebugInfoProvider debugInfoProvider) {
222240 String fileName = debugTypeInfo .fileName ();
223241 Path filePath = debugTypeInfo .filePath ();
224242 Path cachePath = debugTypeInfo .cachePath ();
225- addTypeEntry (typeName , fileName , filePath , cachePath , byteSize , typeKind );
243+ addTypeEntry (idType , typeName , fileName , filePath , cachePath , byteSize , typeKind );
226244 }));
227245
228246 /* Now we can cross reference static and instance field details. */
229247 debugInfoProvider .typeInfoProvider ().forEach (debugTypeInfo -> debugTypeInfo .debugContext ((debugContext ) -> {
230- String typeName = TypeEntry .canonicalize (debugTypeInfo .typeName ());
248+ ResolvedJavaType idType = debugTypeInfo .idType ();
249+ String typeName = debugTypeInfo .typeName ();
231250 DebugTypeKind typeKind = debugTypeInfo .typeKind ();
232251
233252 debugContext .log (DebugContext .INFO_LEVEL , "Process %s type %s " , typeKind .toString (), typeName );
234- TypeEntry typeEntry = lookupTypeEntry (typeName );
253+ TypeEntry typeEntry = lookupTypeEntry (idType );
235254 typeEntry .addDebugInfo (this , debugTypeInfo , debugContext );
236255 }));
237256
@@ -309,12 +328,15 @@ private TypeEntry createTypeEntry(String typeName, String fileName, Path filePat
309328 return typeEntry ;
310329 }
311330
312- private TypeEntry addTypeEntry (String typeName , String fileName , Path filePath , Path cachePath , int size , DebugTypeKind typeKind ) {
313- TypeEntry typeEntry = typesIndex .get (typeName );
331+ private TypeEntry addTypeEntry (ResolvedJavaType idType , String typeName , String fileName , Path filePath , Path cachePath , int size , DebugTypeKind typeKind ) {
332+ TypeEntry typeEntry = typesIndex .get (idType );
314333 if (typeEntry == null ) {
315334 typeEntry = createTypeEntry (typeName , fileName , filePath , cachePath , size , typeKind );
316335 types .add (typeEntry );
317- typesIndex .put (typeName , typeEntry );
336+ typesIndex .put (idType , typeEntry );
337+ if (typeName .equals ("java.lang.Object" )) {
338+ objectClass = (ClassEntry ) typeEntry ;
339+ }
318340 } else {
319341 if (!(typeEntry .isClass ())) {
320342 assert ((ClassEntry ) typeEntry ).getFileName ().equals (fileName );
@@ -323,22 +345,26 @@ private TypeEntry addTypeEntry(String typeName, String fileName, Path filePath,
323345 return typeEntry ;
324346 }
325347
326- public TypeEntry lookupTypeEntry (String typeName ) {
327- TypeEntry typeEntry = typesIndex .get (typeName );
348+ public TypeEntry lookupTypeEntry (ResolvedJavaType type ) {
349+ TypeEntry typeEntry = typesIndex .get (type );
328350 if (typeEntry == null ) {
329- throw new RuntimeException ("type entry not found " + typeName );
351+ throw new RuntimeException ("type entry not found " + type . getName () );
330352 }
331353 return typeEntry ;
332354 }
333355
334- ClassEntry lookupClassEntry (String typeName ) {
335- TypeEntry typeEntry = typesIndex .get (typeName );
356+ ClassEntry lookupClassEntry (ResolvedJavaType type ) {
357+ TypeEntry typeEntry = typesIndex .get (type );
336358 if (typeEntry == null || !(typeEntry .isClass ())) {
337- throw new RuntimeException ("class entry not found " + typeName );
359+ throw new RuntimeException ("class entry not found " + type . getName () );
338360 }
339361 return (ClassEntry ) typeEntry ;
340362 }
341363
364+ public ClassEntry lookupObjectClass () {
365+ return objectClass ;
366+ }
367+
342368 /**
343369 * Recursively creates subranges based on DebugLocationInfo including, and appropriately
344370 * linking, nested inline subranges.
@@ -360,7 +386,7 @@ private Range addSubrange(DebugLocationInfo locationInfo, Range primaryRange, Cl
360386 DebugLocationInfo callerLocationInfo = locationInfo .getCaller ();
361387 boolean isTopLevel = callerLocationInfo == null ;
362388 assert (!isTopLevel || (locationInfo .name ().equals (primaryRange .getMethodName ()) &&
363- TypeEntry . canonicalize ( locationInfo .ownerType ().toJavaName () ).equals (primaryRange .getClassName ())));
389+ locationInfo .ownerType ().toJavaName ().equals (primaryRange .getClassName ())));
364390 Range caller = (isTopLevel ? primaryRange : subRangeIndex .get (callerLocationInfo ));
365391 // the frame tree is walked topdown so inline ranges should always have a caller range
366392 assert caller != null ;
@@ -396,13 +422,13 @@ private ClassEntry ensureClassEntry(ResolvedJavaType type) {
396422 /* See if we already have an entry. */
397423 ClassEntry classEntry = primaryClassesIndex .get (type );
398424 if (classEntry == null ) {
399- TypeEntry typeEntry = typesIndex .get (TypeEntry . canonicalize ( type . toJavaName ()) );
425+ TypeEntry typeEntry = typesIndex .get (type );
400426 assert (typeEntry != null && typeEntry .isClass ());
401427 classEntry = (ClassEntry ) typeEntry ;
402428 primaryClasses .add (classEntry );
403429 primaryClassesIndex .put (type , classEntry );
404430 }
405- assert (classEntry .getTypeName ().equals (TypeEntry . canonicalize ( type .toJavaName () )));
431+ assert (classEntry .getTypeName ().equals (type .toJavaName ()));
406432 return classEntry ;
407433 }
408434
0 commit comments