From 3974499ff4ec8343219a484fde479bb8d6fe3182 Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Thu, 18 Mar 2021 16:52:53 +0200 Subject: [PATCH 01/16] Refactor: Make fields of debugentry.Range final --- .../oracle/objectfile/debugentry/Range.java | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/Range.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/Range.java index 9834420f2915..d2060e4afd62 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/Range.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/Range.java @@ -35,22 +35,22 @@ public class Range { private static final String CLASS_DELIMITER = "."; private FileEntry fileEntry; - private String className; - private String methodName; - private String symbolName; - private String paramSignature; - private String returnTypeName; - private String fullMethodName; - private String fullMethodNameWithParams; - private int lo; - private int hi; - private int line; - private boolean isDeoptTarget; - private int modifiers; + private final String className; + private final String methodName; + private final String symbolName; + private final String paramSignature; + private final String returnTypeName; + private final String fullMethodName; + private final String fullMethodNameWithParams; + private final int lo; + private final int hi; + private final int line; + private final boolean isDeoptTarget; + private final int modifiers; /* * This is null for a primary range. */ - private Range primary; + private final Range primary; /* * Create a primary range. From 5fabaa6b1de7dd7d478289f5c68c6d99ac3ff236 Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Thu, 18 Mar 2021 16:53:34 +0200 Subject: [PATCH 02/16] Refactor: Make debugentry.Range.fileEntry final --- .../src/com/oracle/objectfile/debugentry/Range.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/Range.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/Range.java index d2060e4afd62..6657acb965da 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/Range.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/Range.java @@ -34,7 +34,7 @@ public class Range { private static final String CLASS_DELIMITER = "."; - private FileEntry fileEntry; + private final FileEntry fileEntry; private final String className; private final String methodName; private final String symbolName; @@ -184,10 +184,6 @@ public FileEntry getFileEntry() { return fileEntry; } - public void setFileEntry(FileEntry fileEntry) { - this.fileEntry = fileEntry; - } - public int getModifiers() { return modifiers; } From e361a1e61bed4d2fc535f4511d488c12630fd9b1 Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Tue, 23 Mar 2021 13:28:41 +0200 Subject: [PATCH 03/16] Make ClassEntry.processMethod return the added MethodEntry --- .../com/oracle/objectfile/debugentry/ClassEntry.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java index 7dc4e567b0df..3df28e349181 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java @@ -267,9 +267,9 @@ private void processInterface(String interfaceName, DebugInfoBase debugInfoBase, interfaceClassEntry.addImplementor(this, debugContext); } - protected void processMethod(DebugMethodInfo debugMethodInfo, DebugInfoBase debugInfoBase, DebugContext debugContext) { - String methodName = debugInfoBase.uniqueDebugString(debugMethodInfo.name()); - String resultTypeName = TypeEntry.canonicalize(debugMethodInfo.valueType()); + protected MethodEntry processMethod(DebugMethodInfo debugMethodInfo, DebugInfoBase debugInfoBase, DebugContext debugContext) { + String methodName = debugInfoBase.uniqueDebugString(debugMethodInfo.methodName()); + String resultTypeName = TypeEntry.canonicalize(debugMethodInfo.returnTypeName()); int modifiers = debugMethodInfo.modifiers(); List paramTypes = debugMethodInfo.paramTypes(); List paramNames = debugMethodInfo.paramNames(); @@ -294,7 +294,9 @@ protected void processMethod(DebugMethodInfo debugMethodInfo, DebugInfoBase debu * substitution */ FileEntry methodFileEntry = debugInfoBase.ensureFileEntry(fileName, filePath, cachePath); - methods.add(new MethodEntry(methodFileEntry, methodName, this, resultType, paramTypeArray, paramNameArray, modifiers)); + final MethodEntry methodEntry = new MethodEntry(methodFileEntry, methodName, this, resultType, paramTypeArray, paramNameArray, modifiers); + methods.add(methodEntry); + return methodEntry; } @Override From 90c03c7a1bc454e5bda0a36cb37c39dddd073459 Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Tue, 23 Mar 2021 13:56:44 +0200 Subject: [PATCH 04/16] Refactor: Restructure DebugMethodInfo, DebugCodeInfo and DebugLineInfo This allows code and line info to get access to the properties of the corresponding method. --- .../objectfile/debugentry/ClassEntry.java | 4 +- .../objectfile/debugentry/DebugInfoBase.java | 12 +-- .../debuginfo/DebugInfoProvider.java | 60 ++++-------- .../image/NativeImageDebugInfoProvider.java | 91 +++++++++++++++++-- 4 files changed, 109 insertions(+), 58 deletions(-) diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java index 3df28e349181..a65cd25fdab6 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java @@ -268,8 +268,8 @@ private void processInterface(String interfaceName, DebugInfoBase debugInfoBase, } protected MethodEntry processMethod(DebugMethodInfo debugMethodInfo, DebugInfoBase debugInfoBase, DebugContext debugContext) { - String methodName = debugInfoBase.uniqueDebugString(debugMethodInfo.methodName()); - String resultTypeName = TypeEntry.canonicalize(debugMethodInfo.returnTypeName()); + String methodName = debugInfoBase.uniqueDebugString(debugMethodInfo.name()); + String resultTypeName = TypeEntry.canonicalize(debugMethodInfo.valueType()); int modifiers = debugMethodInfo.modifiers(); List paramTypes = debugMethodInfo.paramTypes(); List paramNames = debugMethodInfo.paramNames(); diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java index 3a4117403b3e..805bcdea07e2 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java @@ -237,16 +237,16 @@ public void installDebugInfo(DebugInfoProvider debugInfoProvider) { String fileName = debugCodeInfo.fileName(); Path filePath = debugCodeInfo.filePath(); Path cachePath = debugCodeInfo.cachePath(); - String className = TypeEntry.canonicalize(debugCodeInfo.className()); - String methodName = debugCodeInfo.methodName(); + String className = TypeEntry.canonicalize(debugCodeInfo.ownerType()); + String methodName = debugCodeInfo.name(); String symbolName = debugCodeInfo.symbolNameForMethod(); String paramSignature = debugCodeInfo.paramSignature(); - String returnTypeName = TypeEntry.canonicalize(debugCodeInfo.returnTypeName()); + String returnTypeName = TypeEntry.canonicalize(debugCodeInfo.valueType()); int lo = debugCodeInfo.addressLo(); int hi = debugCodeInfo.addressHi(); int primaryLine = debugCodeInfo.line(); boolean isDeoptTarget = debugCodeInfo.isDeoptTarget(); - int modifiers = debugCodeInfo.getModifiers(); + int modifiers = debugCodeInfo.modifiers(); /* Search for a method defining this primary range. */ ClassEntry classEntry = ensureClassEntry(className); @@ -257,8 +257,8 @@ public void installDebugInfo(DebugInfoProvider debugInfoProvider) { debugCodeInfo.lineInfoProvider().forEach(debugLineInfo -> { String fileNameAtLine = debugLineInfo.fileName(); Path filePathAtLine = debugLineInfo.filePath(); - String classNameAtLine = TypeEntry.canonicalize(debugLineInfo.className()); - String methodNameAtLine = debugLineInfo.methodName(); + String classNameAtLine = TypeEntry.canonicalize(debugLineInfo.ownerType()); + String methodNameAtLine = debugLineInfo.name(); String symbolNameAtLine = debugLineInfo.symbolNameForMethod(); int loAtLine = lo + debugLineInfo.addressLo(); int hiAtLine = lo + debugLineInfo.addressHi(); diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debuginfo/DebugInfoProvider.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debuginfo/DebugInfoProvider.java index e98b94c817a8..4098643f6005 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debuginfo/DebugInfoProvider.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debuginfo/DebugInfoProvider.java @@ -200,32 +200,33 @@ interface DebugFieldInfo extends DebugMemberInfo { int size(); } - interface DebugMethodInfo extends DebugMemberInfo { - List paramTypes(); - - List paramNames(); - } - - /** - * Access details of a specific compiled method. - */ - interface DebugCodeInfo extends DebugFileInfo { - void debugContext(Consumer action); + interface DebugMethodInfo extends DebugMemberInfo{ + /** + * @return a string identifying the method parameters. + */ + String paramSignature(); /** - * @return the fully qualified name of the class owning the compiled method. + * @return an array of Strings identifying the method parameters. */ - String className(); + List paramTypes(); /** - * @return the name of the compiled method including signature. + * @return an array of Strings with the method parameters' names. */ - String methodName(); + List paramNames(); /** * @return the symbolNameForMethod string */ String symbolNameForMethod(); + } + + /** + * Access details of a specific compiled method. + */ + interface DebugCodeInfo extends DebugMethodInfo { + void debugContext(Consumer action); /** * @return the lowest address containing code generated for the method represented as an @@ -250,16 +251,6 @@ interface DebugCodeInfo extends DebugFileInfo { */ Stream lineInfoProvider(); - /** - * @return a string identifying the method parameters. - */ - String paramSignature(); - - /** - * @return a string identifying the method return type. - */ - String returnTypeName(); - /** * @return the size of the method frame between prologue and epilogue. */ @@ -275,8 +266,6 @@ interface DebugCodeInfo extends DebugFileInfo { * @return true if this method has been compiled in as a deoptimization target */ boolean isDeoptTarget(); - - int getModifiers(); } /** @@ -302,22 +291,7 @@ interface DebugDataInfo { * Access details of code generated for a specific outer or inlined method at a given line * number. */ - interface DebugLineInfo extends DebugFileInfo { - /** - * @return the fully qualified name of the class owning the outer or inlined method. - */ - String className(); - - /** - * @return the name of the outer or inlined method including signature. - */ - String methodName(); - - /** - * @return the symbolNameForMethod string - */ - String symbolNameForMethod(); - + interface DebugLineInfo extends DebugMethodInfo { /** * @return the lowest address containing code generated for an outer or inlined code segment * reported at this line represented as an offset into the code segment. diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoProvider.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoProvider.java index a644b10ec30e..01ad884bb7f2 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoProvider.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoProvider.java @@ -36,6 +36,7 @@ import java.util.function.Consumer; import java.util.stream.Stream; +import jdk.vm.ci.meta.JavaType; import org.graalvm.compiler.code.CompilationResult; import org.graalvm.compiler.code.SourceMapping; import org.graalvm.compiler.core.common.CompressEncoding; @@ -250,6 +251,13 @@ private static ResolvedJavaType getOriginal(ResolvedJavaType javaType) { return null; } + private static String toJavaName(JavaType javaType) { + if (javaType instanceof HostedType) { + return getJavaType((HostedType) javaType, true).toJavaName(); + } + return javaType.toJavaName(); + } + private final Path cachePath = SubstrateOptions.getDebugInfoSourceCacheRoot(); private abstract class NativeImageDebugFileInfo implements DebugFileInfo { @@ -679,6 +687,11 @@ public String valueType() { return hostedMethod.getSignature().getReturnType(null).toJavaName(); } + @Override + public String paramSignature() { + return hostedMethod.format("%P"); + } + @Override public List paramTypes() { LinkedList paramTypes = new LinkedList<>(); @@ -700,6 +713,11 @@ public List paramNames() { return paramNames; } + @Override + public String symbolNameForMethod() { + return NativeImage.localSymbolNameForMethod(hostedMethod); + } + @Override public int modifiers() { return hostedMethod.getModifiers(); @@ -858,12 +876,12 @@ public void debugContext(Consumer action) { } @Override - public String className() { + public String ownerType() { return getJavaType(hostedMethod, true).toJavaName(); } @Override - public String methodName() { + public String name() { ResolvedJavaMethod targetMethod = hostedMethod.getWrapped().getWrapped(); if (targetMethod instanceof SubstitutionMethod) { targetMethod = ((SubstitutionMethod) targetMethod).getOriginal(); @@ -894,7 +912,7 @@ public String paramSignature() { } @Override - public String returnTypeName() { + public String valueType() { return hostedMethod.format("%R"); } @@ -958,11 +976,33 @@ public List getFrameSizeChanges() { @Override public boolean isDeoptTarget() { - return methodName().endsWith(HostedMethod.METHOD_NAME_DEOPT_SUFFIX); + return name().endsWith(HostedMethod.METHOD_NAME_DEOPT_SUFFIX); + } + + @Override + public List paramTypes() { + LinkedList paramTypes = new LinkedList<>(); + Signature signature = hostedMethod.getSignature(); + for (int i = 0; i < signature.getParameterCount(false); i++) { + final JavaType parameterType = signature.getParameterType(i, null); + paramTypes.add(toJavaName(parameterType)); + } + return paramTypes; } @Override - public int getModifiers() { + public List paramNames() { + /* Can only provide blank names for now. */ + LinkedList paramNames = new LinkedList<>(); + Signature signature = hostedMethod.getSignature(); + for (int i = 0; i < signature.getParameterCount(false); i++) { + paramNames.add(""); + } + return paramNames; + } + + @Override + public int modifiers() { return hostedMethod.getModifiers(); } } @@ -1022,12 +1062,12 @@ public Path cachePath() { } @Override - public String className() { + public String ownerType() { return method.format("%H"); } @Override - public String methodName() { + public String name() { ResolvedJavaMethod targetMethod = method; while (targetMethod instanceof WrappedJavaMethod) { targetMethod = ((WrappedJavaMethod) targetMethod).getWrapped(); @@ -1057,6 +1097,16 @@ public String methodName() { return name; } + @Override + public String valueType() { + return method.format("%R"); + } + + @Override + public String paramSignature() { + return method.format("%P"); + } + @Override public String symbolNameForMethod() { return NativeImage.localSymbolNameForMethod(method); @@ -1081,6 +1131,33 @@ public int line() { return -1; } + @Override + public List paramTypes() { + LinkedList paramTypes = new LinkedList<>(); + Signature signature = method.getSignature(); + for (int i = 0; i < signature.getParameterCount(false); i++) { + final JavaType parameterType = signature.getParameterType(i, null); + paramTypes.add(toJavaName(parameterType)); + } + return paramTypes; + } + + @Override + public List paramNames() { + /* Can only provide blank names for now. */ + LinkedList paramNames = new LinkedList<>(); + Signature signature = method.getSignature(); + for (int i = 0; i < signature.getParameterCount(false); i++) { + paramNames.add(""); + } + return paramNames; + } + + @Override + public int modifiers() { + return method.getModifiers(); + } + @SuppressWarnings("try") private void computeFullFilePath() { ResolvedJavaType declaringClass = method.getDeclaringClass(); From b384283b5ac0e455e66648c0d661ce5410bdd863 Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Tue, 23 Mar 2021 14:12:30 +0200 Subject: [PATCH 05/16] Associate Ranges with MethodEntries --- .../objectfile/debugentry/ClassEntry.java | 22 +++++-- .../objectfile/debugentry/DebugInfoBase.java | 12 ++-- .../oracle/objectfile/debugentry/Range.java | 60 ++++++++----------- .../elf/dwarf/DwarfInfoSectionImpl.java | 20 +++---- 4 files changed, 55 insertions(+), 59 deletions(-) diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java index a65cd25fdab6..05d1fd815082 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java @@ -337,10 +337,9 @@ public ClassEntry getSuperClass() { return superClass; } - public Range makePrimaryRange(String methodName, String symbolName, String paramSignature, String returnTypeName, StringTable stringTable, FileEntry primaryFileEntry, int lo, - int hi, int primaryLine, - int modifiers, boolean isDeoptTarget) { - FileEntry fileEntryToUse = primaryFileEntry; + public Range makePrimaryRange(String methodName, String symbolName, String paramSignature, String returnTypeName, StringTable stringTable, MethodEntry method, int lo, + int hi, int primaryLine, boolean isDeoptTarget) { + FileEntry fileEntryToUse = method.fileEntry; if (fileEntryToUse == null) { /* * Search for a matching method to supply the file entry or failing that use the one @@ -358,6 +357,19 @@ public Range makePrimaryRange(String methodName, String symbolName, String param fileEntryToUse = this.fileEntry; } } - return new Range(this.typeName, methodName, symbolName, paramSignature, returnTypeName, stringTable, fileEntryToUse, lo, hi, primaryLine, modifiers, isDeoptTarget); + return new Range(symbolName, stringTable, method, fileEntryToUse, lo, hi, primaryLine, isDeoptTarget); + } + + public MethodEntry ensureMethodEntry(DebugInfoProvider.DebugMethodInfo debugMethodInfo, DebugInfoBase debugInfoBase, DebugContext debugContext) { + String methodName = debugInfoBase.uniqueDebugString(debugMethodInfo.name()); + String paramSignature = debugMethodInfo.paramSignature(); + String returnTypeName = debugMethodInfo.valueType(); + // TODO improve data structure to avoid loops... + for (MethodEntry methodEntry : methods) { + if (methodEntry.match(methodName, paramSignature, returnTypeName)) { + return methodEntry; + } + } + return processMethod(debugMethodInfo, debugInfoBase, debugContext); } } diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java index 805bcdea07e2..fae22206ae67 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java @@ -236,7 +236,6 @@ public void installDebugInfo(DebugInfoProvider debugInfoProvider) { */ String fileName = debugCodeInfo.fileName(); Path filePath = debugCodeInfo.filePath(); - Path cachePath = debugCodeInfo.cachePath(); String className = TypeEntry.canonicalize(debugCodeInfo.ownerType()); String methodName = debugCodeInfo.name(); String symbolName = debugCodeInfo.symbolNameForMethod(); @@ -246,12 +245,11 @@ public void installDebugInfo(DebugInfoProvider debugInfoProvider) { int hi = debugCodeInfo.addressHi(); int primaryLine = debugCodeInfo.line(); boolean isDeoptTarget = debugCodeInfo.isDeoptTarget(); - int modifiers = debugCodeInfo.modifiers(); /* Search for a method defining this primary range. */ ClassEntry classEntry = ensureClassEntry(className); - FileEntry fileEntry = ensureFileEntry(fileName, filePath, cachePath); - Range primaryRange = classEntry.makePrimaryRange(methodName, symbolName, paramSignature, returnTypeName, stringTable, fileEntry, lo, hi, primaryLine, modifiers, isDeoptTarget); + MethodEntry methodEntry = classEntry.ensureMethodEntry(debugCodeInfo, this, debugContext); + Range primaryRange = classEntry.makePrimaryRange(methodName, symbolName, paramSignature, returnTypeName, stringTable, methodEntry, lo, hi, primaryLine, isDeoptTarget); debugContext.log(DebugContext.INFO_LEVEL, "PrimaryRange %s.%s %s %s:%d [0x%x, 0x%x]", className, methodName, filePath, fileName, primaryLine, lo, hi); classEntry.indexPrimary(primaryRange, debugCodeInfo.getFrameSizeChanges(), debugCodeInfo.getFrameSize()); debugCodeInfo.lineInfoProvider().forEach(debugLineInfo -> { @@ -263,13 +261,13 @@ public void installDebugInfo(DebugInfoProvider debugInfoProvider) { int loAtLine = lo + debugLineInfo.addressLo(); int hiAtLine = lo + debugLineInfo.addressHi(); int line = debugLineInfo.line(); - Path cachePathAtLine = debugLineInfo.cachePath(); /* * Record all subranges even if they have no line or file so we at least get a * symbol for them and don't see a break in the address range. */ - FileEntry subFileEntry = ensureFileEntry(fileNameAtLine, filePathAtLine, cachePathAtLine); - Range subRange = new Range(classNameAtLine, methodNameAtLine, symbolNameAtLine, stringTable, subFileEntry, loAtLine, hiAtLine, line, primaryRange); + ClassEntry subClassEntry = ensureClassEntry(classNameAtLine); + MethodEntry subMethodEntry = subClassEntry.ensureMethodEntry(debugLineInfo, this, debugContext); + Range subRange = new Range(symbolNameAtLine, stringTable, subMethodEntry, loAtLine, hiAtLine, line, primaryRange); classEntry.indexSubRange(subRange); try (DebugContext.Scope s = debugContext.scope("Subranges")) { debugContext.log(DebugContext.VERBOSE_LEVEL, "SubRange %s.%s %s %s:%d 0x%x, 0x%x]", classNameAtLine, methodNameAtLine, filePathAtLine, fileNameAtLine, line, loAtLine, hiAtLine); diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/Range.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/Range.java index 6657acb965da..9bea361bef6a 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/Range.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/Range.java @@ -35,18 +35,13 @@ public class Range { private static final String CLASS_DELIMITER = "."; private final FileEntry fileEntry; - private final String className; - private final String methodName; + private MethodEntry methodEntry; private final String symbolName; - private final String paramSignature; - private final String returnTypeName; - private final String fullMethodName; private final String fullMethodNameWithParams; private final int lo; private final int hi; private final int line; private final boolean isDeoptTarget; - private final int modifiers; /* * This is null for a primary range. */ @@ -55,41 +50,36 @@ public class Range { /* * Create a primary range. */ - public Range(String className, String methodName, String symbolName, String paramSignature, String returnTypeName, StringTable stringTable, FileEntry fileEntry, int lo, int hi, int line, - int modifiers, boolean isDeoptTarget) { - this(className, methodName, symbolName, paramSignature, returnTypeName, stringTable, fileEntry, lo, hi, line, modifiers, isDeoptTarget, null); + public Range(String symbolName, StringTable stringTable, MethodEntry methodEntry, FileEntry fileEntry, int lo, int hi, int line, + boolean isDeoptTarget) { + this(symbolName, stringTable, methodEntry, fileEntry, lo, hi, line, isDeoptTarget, null); } /* * Create a secondary range. */ - public Range(String className, String methodName, String symbolName, StringTable stringTable, FileEntry fileEntry, int lo, int hi, int line, - Range primary) { - this(className, methodName, symbolName, "", "", stringTable, fileEntry, lo, hi, line, 0, false, primary); + public Range(String symbolName, StringTable stringTable, MethodEntry methodEntry, int lo, int hi, int line, Range primary) { + this(symbolName, stringTable, methodEntry, methodEntry.fileEntry, lo, hi, line, false, primary); } /* * Create a primary or secondary range. */ - private Range(String className, String methodName, String symbolName, String paramSignature, String returnTypeName, StringTable stringTable, FileEntry fileEntry, int lo, int hi, int line, - int modifiers, boolean isDeoptTarget, Range primary) { - this.fileEntry = fileEntry; + private Range(String symbolName, StringTable stringTable, MethodEntry methodEntry, FileEntry fileEntry, int lo, int hi, int line, + boolean isDeoptTarget, Range primary) { + this.fileEntry = fileEntry; // TODO remove and use fileEntry from MethodEntry if (fileEntry != null) { stringTable.uniqueDebugString(fileEntry.getFileName()); stringTable.uniqueDebugString(fileEntry.getPathName()); } - this.className = stringTable.uniqueString(className); - this.methodName = stringTable.uniqueString(methodName); + assert methodEntry != null; + this.methodEntry = methodEntry; this.symbolName = stringTable.uniqueString(symbolName); - this.paramSignature = stringTable.uniqueString(paramSignature); - this.returnTypeName = stringTable.uniqueString(returnTypeName); - this.fullMethodName = stringTable.uniqueString(constructClassAndMethodName()); this.fullMethodNameWithParams = stringTable.uniqueString(constructClassAndMethodNameWithParams()); this.lo = lo; this.hi = hi; this.line = line; this.isDeoptTarget = isDeoptTarget; - this.modifiers = modifiers; this.primary = primary; } @@ -106,11 +96,11 @@ public Range getPrimary() { } public String getClassName() { - return className; + return methodEntry.ownerType.typeName; } public String getMethodName() { - return methodName; + return methodEntry.memberName; } public String getSymbolName() { @@ -130,7 +120,7 @@ public int getLine() { } public String getFullMethodName() { - return fullMethodName; + return constructClassAndMethodName(); } public String getFullMethodNameWithParams() { @@ -143,23 +133,23 @@ public boolean isDeoptTarget() { private String getExtendedMethodName(boolean includeClass, boolean includeParams, boolean includeReturnType) { StringBuilder builder = new StringBuilder(); - if (includeReturnType && returnTypeName.length() > 0) { - builder.append(returnTypeName); + if (includeReturnType && methodEntry.valueType.typeName.length() > 0) { + builder.append(methodEntry.valueType.typeName); builder.append(' '); } - if (includeClass && className != null) { - builder.append(className); + if (includeClass && getClassName() != null) { + builder.append(getClassName()); builder.append(CLASS_DELIMITER); } - builder.append(methodName); + builder.append(getMethodName()); if (includeParams) { builder.append('('); - builder.append(paramSignature); + builder.append(String.join(", ", methodEntry.paramNames)); builder.append(')'); } if (includeReturnType) { builder.append(" "); - builder.append(returnTypeName); + builder.append(methodEntry.valueType.typeName); } return builder.toString(); } @@ -173,11 +163,11 @@ private String constructClassAndMethodNameWithParams() { } public String getMethodReturnTypeName() { - return returnTypeName; + return methodEntry.valueType.typeName; } - public String getParamSignature() { - return paramSignature; + public TypeEntry[] getParamTypes() { + return methodEntry.paramTypes; } public FileEntry getFileEntry() { @@ -185,7 +175,7 @@ public FileEntry getFileEntry() { } public int getModifiers() { - return modifiers; + return methodEntry.modifiers; } @Override diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/dwarf/DwarfInfoSectionImpl.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/dwarf/DwarfInfoSectionImpl.java index 4f501d4738dd..39ac113011f7 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/dwarf/DwarfInfoSectionImpl.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/dwarf/DwarfInfoSectionImpl.java @@ -724,18 +724,14 @@ private int writeMethodParameterDeclarations(DebugContext context, ClassEntry cl if (!Modifier.isStatic(range.getModifiers())) { pos = writeMethodParameterDeclaration(context, "this", classEntry.getTypeName(), true, isSpecification, buffer, pos); } - String paramsString = range.getParamSignature(); - if (!paramsString.isEmpty()) { - String[] paramTypes = paramsString.split(","); - for (int i = 0; i < paramTypes.length; i++) { - String paramName = uniqueDebugString(""); - String paramTypeName = paramTypes[i].trim(); - FileEntry fileEntry = range.getFileEntry(); - if (fileEntry != null) { - pos = writeMethodParameterDeclaration(context, paramName, paramTypeName, false, isSpecification, buffer, pos); - } else { - pos = writeMethodParameterDeclaration(context, paramTypeName, paramTypeName, false, isSpecification, buffer, pos); - } + for (TypeEntry paramType : range.getParamTypes()) { + String paramTypeName = paramType.getTypeName(); + String paramName = uniqueDebugString(""); + FileEntry fileEntry = range.getFileEntry(); + if (fileEntry != null) { + pos = writeMethodParameterDeclaration(context, paramName, paramTypeName, false, isSpecification, buffer, pos); + } else { + pos = writeMethodParameterDeclaration(context, paramTypeName, paramTypeName, false, isSpecification, buffer, pos); } } return pos; From 8390fd26f3df037c0eef8f2784ff76e74b09b2fc Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Tue, 23 Mar 2021 14:23:12 +0200 Subject: [PATCH 06/16] Fix NativeImageDebugLineInfo.ownerType() to get original from substs --- .../svm/hosted/image/NativeImageDebugInfoProvider.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoProvider.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoProvider.java index 01ad884bb7f2..df03832bbfd8 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoProvider.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoProvider.java @@ -1063,7 +1063,11 @@ public Path cachePath() { @Override public String ownerType() { - return method.format("%H"); + if (method instanceof HostedMethod) { + return getJavaType((HostedMethod) method, true).toJavaName(); + } else { + return method.getDeclaringClass().toJavaName(); + } } @Override From f485a3c15f5e29daf480657c0bfa22662f8005ae Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Tue, 23 Mar 2021 16:25:22 +0200 Subject: [PATCH 07/16] Refactor: Migrate isDeoptTarget to DebugMethodInfo And cache value in MethodEntry --- .../oracle/objectfile/debugentry/ClassEntry.java | 6 +++--- .../oracle/objectfile/debugentry/DebugInfoBase.java | 3 +-- .../oracle/objectfile/debugentry/MethodEntry.java | 8 +++++++- .../src/com/oracle/objectfile/debugentry/Range.java | 13 +++++-------- .../objectfile/debuginfo/DebugInfoProvider.java | 12 ++++++------ .../hosted/image/NativeImageDebugInfoProvider.java | 10 ++++++++++ 6 files changed, 32 insertions(+), 20 deletions(-) diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java index 05d1fd815082..2974c262a089 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java @@ -294,7 +294,7 @@ protected MethodEntry processMethod(DebugMethodInfo debugMethodInfo, DebugInfoBa * substitution */ FileEntry methodFileEntry = debugInfoBase.ensureFileEntry(fileName, filePath, cachePath); - final MethodEntry methodEntry = new MethodEntry(methodFileEntry, methodName, this, resultType, paramTypeArray, paramNameArray, modifiers); + final MethodEntry methodEntry = new MethodEntry(methodFileEntry, methodName, this, resultType, paramTypeArray, paramNameArray, modifiers, debugMethodInfo.isDeoptTarget()); methods.add(methodEntry); return methodEntry; } @@ -338,7 +338,7 @@ public ClassEntry getSuperClass() { } public Range makePrimaryRange(String methodName, String symbolName, String paramSignature, String returnTypeName, StringTable stringTable, MethodEntry method, int lo, - int hi, int primaryLine, boolean isDeoptTarget) { + int hi, int primaryLine) { FileEntry fileEntryToUse = method.fileEntry; if (fileEntryToUse == null) { /* @@ -357,7 +357,7 @@ public Range makePrimaryRange(String methodName, String symbolName, String param fileEntryToUse = this.fileEntry; } } - return new Range(symbolName, stringTable, method, fileEntryToUse, lo, hi, primaryLine, isDeoptTarget); + return new Range(symbolName, stringTable, method, fileEntryToUse, lo, hi, primaryLine); } public MethodEntry ensureMethodEntry(DebugInfoProvider.DebugMethodInfo debugMethodInfo, DebugInfoBase debugInfoBase, DebugContext debugContext) { diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java index fae22206ae67..8e7da1ff2150 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java @@ -244,12 +244,11 @@ public void installDebugInfo(DebugInfoProvider debugInfoProvider) { int lo = debugCodeInfo.addressLo(); int hi = debugCodeInfo.addressHi(); int primaryLine = debugCodeInfo.line(); - boolean isDeoptTarget = debugCodeInfo.isDeoptTarget(); /* Search for a method defining this primary range. */ ClassEntry classEntry = ensureClassEntry(className); MethodEntry methodEntry = classEntry.ensureMethodEntry(debugCodeInfo, this, debugContext); - Range primaryRange = classEntry.makePrimaryRange(methodName, symbolName, paramSignature, returnTypeName, stringTable, methodEntry, lo, hi, primaryLine, isDeoptTarget); + Range primaryRange = classEntry.makePrimaryRange(methodName, symbolName, paramSignature, returnTypeName, stringTable, methodEntry, lo, hi, primaryLine); debugContext.log(DebugContext.INFO_LEVEL, "PrimaryRange %s.%s %s %s:%d [0x%x, 0x%x]", className, methodName, filePath, fileName, primaryLine, lo, hi); classEntry.indexPrimary(primaryRange, debugCodeInfo.getFrameSizeChanges(), debugCodeInfo.getFrameSize()); debugCodeInfo.lineInfoProvider().forEach(debugLineInfo -> { diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/MethodEntry.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/MethodEntry.java index 7b84995d6cd5..38f13550e807 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/MethodEntry.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/MethodEntry.java @@ -29,13 +29,15 @@ public class MethodEntry extends MemberEntry { TypeEntry[] paramTypes; String[] paramNames; + final boolean isDeoptTarget; - public MethodEntry(FileEntry fileEntry, String methodName, ClassEntry ownerType, TypeEntry valueType, TypeEntry[] paramTypes, String[] paramNames, int modifiers) { + public MethodEntry(FileEntry fileEntry, String methodName, ClassEntry ownerType, TypeEntry valueType, TypeEntry[] paramTypes, String[] paramNames, int modifiers, boolean isDeoptTarget) { super(fileEntry, methodName, ownerType, valueType, modifiers); assert ((paramTypes == null && paramNames == null) || (paramTypes != null && paramNames != null && paramTypes.length == paramNames.length)); this.paramTypes = paramTypes; this.paramNames = paramNames; + this.isDeoptTarget = isDeoptTarget; } public String methodName() { @@ -94,4 +96,8 @@ public boolean match(String methodName, String paramSignature, String returnType } return true; } + + public boolean isDeoptTarget() { + return isDeoptTarget; + } } diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/Range.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/Range.java index 9bea361bef6a..a3d6e1c0db28 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/Range.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/Range.java @@ -41,7 +41,6 @@ public class Range { private final int lo; private final int hi; private final int line; - private final boolean isDeoptTarget; /* * This is null for a primary range. */ @@ -50,23 +49,22 @@ public class Range { /* * Create a primary range. */ - public Range(String symbolName, StringTable stringTable, MethodEntry methodEntry, FileEntry fileEntry, int lo, int hi, int line, - boolean isDeoptTarget) { - this(symbolName, stringTable, methodEntry, fileEntry, lo, hi, line, isDeoptTarget, null); + public Range(String symbolName, StringTable stringTable, MethodEntry methodEntry, FileEntry fileEntry, int lo, int hi, int line) { + this(symbolName, stringTable, methodEntry, fileEntry, lo, hi, line, null); } /* * Create a secondary range. */ public Range(String symbolName, StringTable stringTable, MethodEntry methodEntry, int lo, int hi, int line, Range primary) { - this(symbolName, stringTable, methodEntry, methodEntry.fileEntry, lo, hi, line, false, primary); + this(symbolName, stringTable, methodEntry, methodEntry.fileEntry, lo, hi, line, primary); } /* * Create a primary or secondary range. */ private Range(String symbolName, StringTable stringTable, MethodEntry methodEntry, FileEntry fileEntry, int lo, int hi, int line, - boolean isDeoptTarget, Range primary) { + Range primary) { this.fileEntry = fileEntry; // TODO remove and use fileEntry from MethodEntry if (fileEntry != null) { stringTable.uniqueDebugString(fileEntry.getFileName()); @@ -79,7 +77,6 @@ private Range(String symbolName, StringTable stringTable, MethodEntry methodEntr this.lo = lo; this.hi = hi; this.line = line; - this.isDeoptTarget = isDeoptTarget; this.primary = primary; } @@ -128,7 +125,7 @@ public String getFullMethodNameWithParams() { } public boolean isDeoptTarget() { - return isDeoptTarget; + return methodEntry.isDeoptTarget; } private String getExtendedMethodName(boolean includeClass, boolean includeParams, boolean includeReturnType) { diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debuginfo/DebugInfoProvider.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debuginfo/DebugInfoProvider.java index 4098643f6005..5c5729de8eb2 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debuginfo/DebugInfoProvider.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debuginfo/DebugInfoProvider.java @@ -200,7 +200,7 @@ interface DebugFieldInfo extends DebugMemberInfo { int size(); } - interface DebugMethodInfo extends DebugMemberInfo{ + interface DebugMethodInfo extends DebugMemberInfo { /** * @return a string identifying the method parameters. */ @@ -220,6 +220,11 @@ interface DebugMethodInfo extends DebugMemberInfo{ * @return the symbolNameForMethod string */ String symbolNameForMethod(); + + /** + * @return true if this method has been compiled in as a deoptimization target + */ + boolean isDeoptTarget(); } /** @@ -261,11 +266,6 @@ interface DebugCodeInfo extends DebugMethodInfo { * to an empty frame */ List getFrameSizeChanges(); - - /** - * @return true if this method has been compiled in as a deoptimization target - */ - boolean isDeoptTarget(); } /** diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoProvider.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoProvider.java index df03832bbfd8..20e31c2bd8e8 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoProvider.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoProvider.java @@ -718,6 +718,11 @@ public String symbolNameForMethod() { return NativeImage.localSymbolNameForMethod(hostedMethod); } + @Override + public boolean isDeoptTarget() { + return name().endsWith(HostedMethod.METHOD_NAME_DEOPT_SUFFIX); + } + @Override public int modifiers() { return hostedMethod.getModifiers(); @@ -1116,6 +1121,11 @@ public String symbolNameForMethod() { return NativeImage.localSymbolNameForMethod(method); } + @Override + public boolean isDeoptTarget() { + return name().endsWith(HostedMethod.METHOD_NAME_DEOPT_SUFFIX); + } + @Override public int addressLo() { return lo; From 8500f4367ed7890ad3c177c22f211ff8237b1a67 Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Tue, 23 Mar 2021 16:29:45 +0200 Subject: [PATCH 08/16] Refactor: Make MethodEntry fields final --- .../src/com/oracle/objectfile/debugentry/MethodEntry.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/MethodEntry.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/MethodEntry.java index 38f13550e807..5b0fcb1092a2 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/MethodEntry.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/MethodEntry.java @@ -27,8 +27,8 @@ package com.oracle.objectfile.debugentry; public class MethodEntry extends MemberEntry { - TypeEntry[] paramTypes; - String[] paramNames; + final TypeEntry[] paramTypes; + final String[] paramNames; final boolean isDeoptTarget; public MethodEntry(FileEntry fileEntry, String methodName, ClassEntry ownerType, TypeEntry valueType, TypeEntry[] paramTypes, String[] paramNames, int modifiers, boolean isDeoptTarget) { From bdb9490d423856ec3dc722bf5c9ee192777d4f33 Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Tue, 23 Mar 2021 16:36:34 +0200 Subject: [PATCH 09/16] Refactor: Avoid Qualified types in ClassEntry --- .../src/com/oracle/objectfile/debugentry/ClassEntry.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java index 2974c262a089..fa7df11c5625 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java @@ -26,7 +26,7 @@ package com.oracle.objectfile.debugentry; -import com.oracle.objectfile.debuginfo.DebugInfoProvider; +import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugFieldInfo; import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugFrameSizeChange; import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugMethodInfo; import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugTypeInfo; @@ -300,7 +300,7 @@ protected MethodEntry processMethod(DebugMethodInfo debugMethodInfo, DebugInfoBa } @Override - protected FieldEntry addField(DebugInfoProvider.DebugFieldInfo debugFieldInfo, DebugInfoBase debugInfoBase, DebugContext debugContext) { + protected FieldEntry addField(DebugFieldInfo debugFieldInfo, DebugInfoBase debugInfoBase, DebugContext debugContext) { FieldEntry fieldEntry = super.addField(debugFieldInfo, debugInfoBase, debugContext); FileEntry fieldFileEntry = fieldEntry.getFileEntry(); if (fieldFileEntry != null) { @@ -360,7 +360,7 @@ public Range makePrimaryRange(String methodName, String symbolName, String param return new Range(symbolName, stringTable, method, fileEntryToUse, lo, hi, primaryLine); } - public MethodEntry ensureMethodEntry(DebugInfoProvider.DebugMethodInfo debugMethodInfo, DebugInfoBase debugInfoBase, DebugContext debugContext) { + public MethodEntry ensureMethodEntry(DebugMethodInfo debugMethodInfo, DebugInfoBase debugInfoBase, DebugContext debugContext) { String methodName = debugInfoBase.uniqueDebugString(debugMethodInfo.name()); String paramSignature = debugMethodInfo.paramSignature(); String returnTypeName = debugMethodInfo.valueType(); From 70792d9ae44148d55d1611662964c48b7f132e0a Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Tue, 23 Mar 2021 20:36:34 +0200 Subject: [PATCH 10/16] Remove redundant lookup for fileEntry ClassEntry.makePrimaryRange(...) --- .../objectfile/debugentry/ClassEntry.java | 20 +++---------------- .../objectfile/debugentry/DebugInfoBase.java | 4 +--- .../oracle/objectfile/debugentry/Range.java | 2 +- 3 files changed, 5 insertions(+), 21 deletions(-) diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java index fa7df11c5625..2bb7369844ff 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java @@ -337,25 +337,11 @@ public ClassEntry getSuperClass() { return superClass; } - public Range makePrimaryRange(String methodName, String symbolName, String paramSignature, String returnTypeName, StringTable stringTable, MethodEntry method, int lo, - int hi, int primaryLine) { + public Range makePrimaryRange(String symbolName, StringTable stringTable, MethodEntry method, int lo, int hi, int primaryLine) { FileEntry fileEntryToUse = method.fileEntry; if (fileEntryToUse == null) { - /* - * Search for a matching method to supply the file entry or failing that use the one - * from this class. - */ - for (MethodEntry methodEntry : methods) { - if (methodEntry.match(methodName, paramSignature, returnTypeName)) { - /* maybe the method's file entry */ - fileEntryToUse = methodEntry.getFileEntry(); - break; - } - } - if (fileEntryToUse == null) { - /* Last chance is the class's file entry. */ - fileEntryToUse = this.fileEntry; - } + /* Last chance is the class's file entry. */ + fileEntryToUse = this.fileEntry; } return new Range(symbolName, stringTable, method, fileEntryToUse, lo, hi, primaryLine); } diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java index 8e7da1ff2150..e06b29e22562 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java @@ -239,8 +239,6 @@ public void installDebugInfo(DebugInfoProvider debugInfoProvider) { String className = TypeEntry.canonicalize(debugCodeInfo.ownerType()); String methodName = debugCodeInfo.name(); String symbolName = debugCodeInfo.symbolNameForMethod(); - String paramSignature = debugCodeInfo.paramSignature(); - String returnTypeName = TypeEntry.canonicalize(debugCodeInfo.valueType()); int lo = debugCodeInfo.addressLo(); int hi = debugCodeInfo.addressHi(); int primaryLine = debugCodeInfo.line(); @@ -248,7 +246,7 @@ public void installDebugInfo(DebugInfoProvider debugInfoProvider) { /* Search for a method defining this primary range. */ ClassEntry classEntry = ensureClassEntry(className); MethodEntry methodEntry = classEntry.ensureMethodEntry(debugCodeInfo, this, debugContext); - Range primaryRange = classEntry.makePrimaryRange(methodName, symbolName, paramSignature, returnTypeName, stringTable, methodEntry, lo, hi, primaryLine); + Range primaryRange = classEntry.makePrimaryRange(symbolName, stringTable, methodEntry, lo, hi, primaryLine); debugContext.log(DebugContext.INFO_LEVEL, "PrimaryRange %s.%s %s %s:%d [0x%x, 0x%x]", className, methodName, filePath, fileName, primaryLine, lo, hi); classEntry.indexPrimary(primaryRange, debugCodeInfo.getFrameSizeChanges(), debugCodeInfo.getFrameSize()); debugCodeInfo.lineInfoProvider().forEach(debugLineInfo -> { diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/Range.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/Range.java index a3d6e1c0db28..dd82d22565b1 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/Range.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/Range.java @@ -65,7 +65,7 @@ public Range(String symbolName, StringTable stringTable, MethodEntry methodEntry */ private Range(String symbolName, StringTable stringTable, MethodEntry methodEntry, FileEntry fileEntry, int lo, int hi, int line, Range primary) { - this.fileEntry = fileEntry; // TODO remove and use fileEntry from MethodEntry + this.fileEntry = fileEntry; if (fileEntry != null) { stringTable.uniqueDebugString(fileEntry.getFileName()); stringTable.uniqueDebugString(fileEntry.getPathName()); From 94957c48c44dbd9e7cbb24d173d51c629d47d921 Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Thu, 8 Apr 2021 15:26:11 +0300 Subject: [PATCH 11/16] Enhance MethodEntries creation and verification Following Andrew Dinn's recommendation in https://github.com/oracle/graal/pull/3304#issuecomment-815926794, this patch creates the necessary `MethodEntry`s for each `ClassEntry` using the methodInfoProvider, It then sorts the methods list to ensure faster lookups in the phase of linking `Range`s to `MethodEntry`s. It also adds assertions to ensure that the methods list is sorted and that there are no duplicate entries in it. --- .../objectfile/debugentry/ClassEntry.java | 36 +++++++++++----- .../objectfile/debugentry/DebugInfoBase.java | 6 +-- .../objectfile/debugentry/MethodEntry.java | 43 ++++++++++++++----- 3 files changed, 61 insertions(+), 24 deletions(-) diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java index 2bb7369844ff..3b57505b6860 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2020, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -35,9 +35,11 @@ import org.graalvm.compiler.debug.DebugContext; import java.nio.file.Path; +import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import java.util.ListIterator; import java.util.Map; /** @@ -134,7 +136,9 @@ public void addDebugInfo(DebugInfoBase debugInfoBase, DebugTypeInfo debugTypeInf /* Add details of fields and field types */ debugInstanceTypeInfo.fieldInfoProvider().forEach(debugFieldInfo -> this.processField(debugFieldInfo, debugInfoBase, debugContext)); /* Add details of methods and method types */ - debugInstanceTypeInfo.methodInfoProvider().forEach(methodFieldInfo -> this.processMethod(methodFieldInfo, debugInfoBase, debugContext)); + debugInstanceTypeInfo.methodInfoProvider().forEach(methodFieldInfo -> this.methods.add(this.processMethod(methodFieldInfo, debugInfoBase, debugContext))); + /* Sort methods to improve lookup speed */ + this.methods.sort(MethodEntry::compareTo); } public void indexPrimary(Range primary, List frameSizeInfos, int frameSize) { @@ -294,9 +298,7 @@ protected MethodEntry processMethod(DebugMethodInfo debugMethodInfo, DebugInfoBa * substitution */ FileEntry methodFileEntry = debugInfoBase.ensureFileEntry(fileName, filePath, cachePath); - final MethodEntry methodEntry = new MethodEntry(methodFileEntry, methodName, this, resultType, paramTypeArray, paramNameArray, modifiers, debugMethodInfo.isDeoptTarget()); - methods.add(methodEntry); - return methodEntry; + return new MethodEntry(methodFileEntry, methodName, this, resultType, paramTypeArray, paramNameArray, modifiers, debugMethodInfo.isDeoptTarget()); } @Override @@ -346,16 +348,30 @@ public Range makePrimaryRange(String symbolName, StringTable stringTable, Method return new Range(symbolName, stringTable, method, fileEntryToUse, lo, hi, primaryLine); } - public MethodEntry ensureMethodEntry(DebugMethodInfo debugMethodInfo, DebugInfoBase debugInfoBase, DebugContext debugContext) { + public MethodEntry getMethodEntry(DebugMethodInfo debugMethodInfo, DebugInfoBase debugInfoBase, DebugContext debugContext) { + assert listIsSorted(methods); String methodName = debugInfoBase.uniqueDebugString(debugMethodInfo.name()); String paramSignature = debugMethodInfo.paramSignature(); String returnTypeName = debugMethodInfo.valueType(); - // TODO improve data structure to avoid loops... - for (MethodEntry methodEntry : methods) { - if (methodEntry.match(methodName, paramSignature, returnTypeName)) { + ListIterator methodIterator = methods.listIterator(); + while (methodIterator.hasNext()) { + MethodEntry methodEntry = methodIterator.next(); + int comparisonResult = methodEntry.compareTo(methodName, paramSignature, returnTypeName); + if (comparisonResult == 0) { return methodEntry; + } else if (comparisonResult > 0) { + methodIterator.previous(); + break; } } - return processMethod(debugMethodInfo, debugInfoBase, debugContext); + MethodEntry newMethodEntry = processMethod(debugMethodInfo, debugInfoBase, debugContext); + methodIterator.add(newMethodEntry); + return newMethodEntry; + } + + private boolean listIsSorted(List list) { + List copy = new ArrayList<>(list); + copy.sort(MethodEntry::compareTo); + return list.equals(copy); } } diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java index e06b29e22562..8eb7c3e5bec0 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2020, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -245,7 +245,7 @@ public void installDebugInfo(DebugInfoProvider debugInfoProvider) { /* Search for a method defining this primary range. */ ClassEntry classEntry = ensureClassEntry(className); - MethodEntry methodEntry = classEntry.ensureMethodEntry(debugCodeInfo, this, debugContext); + MethodEntry methodEntry = classEntry.getMethodEntry(debugCodeInfo, this, debugContext); Range primaryRange = classEntry.makePrimaryRange(symbolName, stringTable, methodEntry, lo, hi, primaryLine); debugContext.log(DebugContext.INFO_LEVEL, "PrimaryRange %s.%s %s %s:%d [0x%x, 0x%x]", className, methodName, filePath, fileName, primaryLine, lo, hi); classEntry.indexPrimary(primaryRange, debugCodeInfo.getFrameSizeChanges(), debugCodeInfo.getFrameSize()); @@ -263,7 +263,7 @@ public void installDebugInfo(DebugInfoProvider debugInfoProvider) { * symbol for them and don't see a break in the address range. */ ClassEntry subClassEntry = ensureClassEntry(classNameAtLine); - MethodEntry subMethodEntry = subClassEntry.ensureMethodEntry(debugLineInfo, this, debugContext); + MethodEntry subMethodEntry = subClassEntry.getMethodEntry(debugLineInfo, this, debugContext); Range subRange = new Range(symbolNameAtLine, stringTable, subMethodEntry, loAtLine, hiAtLine, line, primaryRange); classEntry.indexSubRange(subRange); try (DebugContext.Scope s = debugContext.scope("Subranges")) { diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/MethodEntry.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/MethodEntry.java index 5b0fcb1092a2..dbf9c2aa9bc4 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/MethodEntry.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/MethodEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2020, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -26,7 +26,7 @@ package com.oracle.objectfile.debugentry; -public class MethodEntry extends MemberEntry { +public class MethodEntry extends MemberEntry implements Comparable { final TypeEntry[] paramTypes; final String[] paramNames; final boolean isDeoptTarget; @@ -74,30 +74,51 @@ public String getParamName(int idx) { return paramNames[idx]; } - public boolean match(String methodName, String paramSignature, String returnTypeName) { - if (!methodName.equals(this.memberName)) { - return false; + public int compareTo(String methodName, String paramSignature, String returnTypeName) { + if (!memberName.equals(methodName)) { + return memberName.compareTo(methodName); } - if (!returnTypeName.equals(valueType.getTypeName())) { - return false; + if (!valueType.getTypeName().equals(returnTypeName)) { + return valueType.getTypeName().compareTo(returnTypeName); } int paramCount = getParamCount(); if (paramCount == 0) { - return paramSignature.trim().length() == 0; + return 0 - paramSignature.trim().length(); } String[] paramTypeNames = paramSignature.split((",")); if (paramCount != paramTypeNames.length) { - return false; + return paramCount - paramTypeNames.length; } for (int i = 0; i < paramCount; i++) { if (!paramTypeNames[i].trim().equals(getParamTypeName(i))) { - return false; + return getParamTypeName(i).compareTo(paramTypeNames[i].trim()); } } - return true; + return 0; } public boolean isDeoptTarget() { return isDeoptTarget; } + + @Override + public int compareTo(MethodEntry other) { + assert other != null; + int result = methodName().compareTo(other.methodName()); + if (result == 0) { + result = valueType.getTypeName().compareTo(other.valueType.getTypeName()); + } + if (result == 0) { + result = getParamCount() - other.getParamCount(); + } + if (result == 0) { + for (int i = 0; i < getParamCount(); i++) { + result = getParamTypeName(i).compareTo(other.getParamTypeName(i)); + if (result != 0) { + break; + } + } + } + return result; + } } From 606f225c0f49237241050cb813569adb27a2d826 Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Mon, 10 May 2021 11:44:24 +0300 Subject: [PATCH 12/16] Refactor: MethodEntry.compareTo --- .../objectfile/debugentry/MethodEntry.java | 59 +++++++++++-------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/MethodEntry.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/MethodEntry.java index dbf9c2aa9bc4..cca95588a76e 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/MethodEntry.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/MethodEntry.java @@ -75,23 +75,29 @@ public String getParamName(int idx) { } public int compareTo(String methodName, String paramSignature, String returnTypeName) { - if (!memberName.equals(methodName)) { - return memberName.compareTo(methodName); + int nameComparison = memberName.compareTo(methodName); + if (nameComparison != 0) { + return nameComparison; } - if (!valueType.getTypeName().equals(returnTypeName)) { - return valueType.getTypeName().compareTo(returnTypeName); - } - int paramCount = getParamCount(); - if (paramCount == 0) { - return 0 - paramSignature.trim().length(); + int typeComparison = valueType.getTypeName().compareTo(returnTypeName); + if (typeComparison != 0) { + return typeComparison; } String[] paramTypeNames = paramSignature.split((",")); - if (paramCount != paramTypeNames.length) { - return paramCount - paramTypeNames.length; + int length; + if (paramSignature.trim().length() == 0) { + length = 0; + } else { + length = paramTypeNames.length; + } + int paramCountComparison = getParamCount() - length; + if (paramCountComparison != 0) { + return paramCountComparison; } - for (int i = 0; i < paramCount; i++) { - if (!paramTypeNames[i].trim().equals(getParamTypeName(i))) { - return getParamTypeName(i).compareTo(paramTypeNames[i].trim()); + for (int i = 0; i < getParamCount(); i++) { + int paraComparison = getParamTypeName(i).compareTo(paramTypeNames[i].trim()); + if (paraComparison != 0) { + return paraComparison; } } return 0; @@ -104,21 +110,24 @@ public boolean isDeoptTarget() { @Override public int compareTo(MethodEntry other) { assert other != null; - int result = methodName().compareTo(other.methodName()); - if (result == 0) { - result = valueType.getTypeName().compareTo(other.valueType.getTypeName()); + int nameComparison = methodName().compareTo(other.methodName()); + if (nameComparison != 0) { + return nameComparison; } - if (result == 0) { - result = getParamCount() - other.getParamCount(); + int typeComparison = valueType.getTypeName().compareTo(other.valueType.getTypeName()); + if (typeComparison != 0) { + return typeComparison; } - if (result == 0) { - for (int i = 0; i < getParamCount(); i++) { - result = getParamTypeName(i).compareTo(other.getParamTypeName(i)); - if (result != 0) { - break; - } + int paramCountComparison = getParamCount() - other.getParamCount(); + if (paramCountComparison != 0) { + return paramCountComparison; + } + for (int i = 0; i < getParamCount(); i++) { + int paramComparison = getParamTypeName(i).compareTo(other.getParamTypeName(i)); + if (paramComparison != 0) { + return paramComparison; } } - return result; + return 0; } } From 37e0d9d7b419913fcd6e39d12219106bcb523c50 Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Mon, 10 May 2021 11:56:44 +0300 Subject: [PATCH 13/16] Optimize NativeImageDebugInfoProvider.paramTypes and paramNames --- .../image/NativeImageDebugInfoProvider.java | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoProvider.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoProvider.java index 20e31c2bd8e8..d2ec18bfa2c4 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoProvider.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoProvider.java @@ -30,6 +30,7 @@ import java.lang.reflect.Modifier; import java.nio.file.Path; +import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.List; @@ -694,9 +695,10 @@ public String paramSignature() { @Override public List paramTypes() { - LinkedList paramTypes = new LinkedList<>(); Signature signature = hostedMethod.getSignature(); - for (int i = 0; i < signature.getParameterCount(false); i++) { + int parameterCount = signature.getParameterCount(false); + List paramTypes = new ArrayList<>(parameterCount); + for (int i = 0; i < parameterCount; i++) { paramTypes.add(signature.getParameterType(i, null).toJavaName()); } return paramTypes; @@ -705,9 +707,10 @@ public List paramTypes() { @Override public List paramNames() { /* Can only provide blank names for now. */ - LinkedList paramNames = new LinkedList<>(); Signature signature = hostedMethod.getSignature(); - for (int i = 0; i < signature.getParameterCount(false); i++) { + int parameterCount = signature.getParameterCount(false); + List paramNames = new ArrayList<>(parameterCount); + for (int i = 0; i < parameterCount; i++) { paramNames.add(""); } return paramNames; @@ -986,10 +989,11 @@ public boolean isDeoptTarget() { @Override public List paramTypes() { - LinkedList paramTypes = new LinkedList<>(); Signature signature = hostedMethod.getSignature(); - for (int i = 0; i < signature.getParameterCount(false); i++) { - final JavaType parameterType = signature.getParameterType(i, null); + int parameterCount = signature.getParameterCount(false); + List paramTypes = new ArrayList<>(parameterCount); + for (int i = 0; i < parameterCount; i++) { + JavaType parameterType = signature.getParameterType(i, null); paramTypes.add(toJavaName(parameterType)); } return paramTypes; @@ -998,9 +1002,10 @@ public List paramTypes() { @Override public List paramNames() { /* Can only provide blank names for now. */ - LinkedList paramNames = new LinkedList<>(); Signature signature = hostedMethod.getSignature(); - for (int i = 0; i < signature.getParameterCount(false); i++) { + int parameterCount = signature.getParameterCount(false); + List paramNames = new ArrayList<>(parameterCount); + for (int i = 0; i < parameterCount; i++) { paramNames.add(""); } return paramNames; @@ -1147,10 +1152,11 @@ public int line() { @Override public List paramTypes() { - LinkedList paramTypes = new LinkedList<>(); Signature signature = method.getSignature(); - for (int i = 0; i < signature.getParameterCount(false); i++) { - final JavaType parameterType = signature.getParameterType(i, null); + int parameterCount = signature.getParameterCount(false); + List paramTypes = new ArrayList<>(parameterCount); + for (int i = 0; i < parameterCount; i++) { + JavaType parameterType = signature.getParameterType(i, null); paramTypes.add(toJavaName(parameterType)); } return paramTypes; @@ -1159,9 +1165,10 @@ public List paramTypes() { @Override public List paramNames() { /* Can only provide blank names for now. */ - LinkedList paramNames = new LinkedList<>(); Signature signature = method.getSignature(); - for (int i = 0; i < signature.getParameterCount(false); i++) { + int parameterCount = signature.getParameterCount(false); + List paramNames = new ArrayList<>(parameterCount); + for (int i = 0; i < parameterCount; i++) { paramNames.add(""); } return paramNames; From e9e0d4804f900ab6996e110c38e53f73af428b63 Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Mon, 10 May 2021 12:11:20 +0300 Subject: [PATCH 14/16] Refactor: Use HostedMethod.isDeoptTarget() --- .../svm/hosted/image/NativeImageDebugInfoProvider.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoProvider.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoProvider.java index d2ec18bfa2c4..2c75d3df49ec 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoProvider.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoProvider.java @@ -723,7 +723,7 @@ public String symbolNameForMethod() { @Override public boolean isDeoptTarget() { - return name().endsWith(HostedMethod.METHOD_NAME_DEOPT_SUFFIX); + return hostedMethod.isDeoptTarget(); } @Override @@ -984,7 +984,7 @@ public List getFrameSizeChanges() { @Override public boolean isDeoptTarget() { - return name().endsWith(HostedMethod.METHOD_NAME_DEOPT_SUFFIX); + return hostedMethod.isDeoptTarget(); } @Override @@ -1128,6 +1128,9 @@ public String symbolNameForMethod() { @Override public boolean isDeoptTarget() { + if (method instanceof HostedMethod) { + return ((HostedMethod) method).isDeoptTarget(); + } return name().endsWith(HostedMethod.METHOD_NAME_DEOPT_SUFFIX); } From e85e3f6798bb6e818ed3f2c74165d68db226c4a4 Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Mon, 10 May 2021 12:56:35 +0300 Subject: [PATCH 15/16] Refactor: make listIsSorted static --- .../src/com/oracle/objectfile/debugentry/ClassEntry.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java index 3b57505b6860..abb8e9133a39 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java @@ -369,7 +369,7 @@ public MethodEntry getMethodEntry(DebugMethodInfo debugMethodInfo, DebugInfoBase return newMethodEntry; } - private boolean listIsSorted(List list) { + private static boolean listIsSorted(List list) { List copy = new ArrayList<>(list); copy.sort(MethodEntry::compareTo); return list.equals(copy); From 0ea21026b4507d2d29908093b548a9e47361347b Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Tue, 11 May 2021 09:55:54 +0300 Subject: [PATCH 16/16] Refactor: Use ArrayList instead of LinkedList --- .../objectfile/debugentry/ClassEntry.java | 24 ++++++++++--------- .../objectfile/debugentry/DebugInfoBase.java | 15 ++++++------ .../debugentry/InterfaceClassEntry.java | 4 ++-- .../objectfile/debugentry/PrimaryEntry.java | 4 ++-- .../debugentry/StructureTypeEntry.java | 4 ++-- .../elf/dwarf/DwarfARangesSectionImpl.java | 10 ++++---- .../elf/dwarf/DwarfInfoSectionImpl.java | 18 +++++++------- 7 files changed, 41 insertions(+), 38 deletions(-) diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java index abb8e9133a39..0e49c67a21be 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java @@ -53,7 +53,7 @@ public class ClassEntry extends StructureTypeEntry { /** * Details of this class's interfaces. */ - protected LinkedList interfaces; + protected List interfaces; /** * Details of the associated file. */ @@ -66,7 +66,7 @@ public class ClassEntry extends StructureTypeEntry { * A list recording details of all primary ranges included in this class sorted by ascending * address range. */ - private LinkedList primaryEntries; + private List primaryEntries; /** * An index identifying primary ranges which have already been encountered. */ @@ -78,7 +78,7 @@ public class ClassEntry extends StructureTypeEntry { /** * A list of the same files. */ - private LinkedList localFiles; + private List localFiles; /** * An index of all primary and secondary dirs referenced from this class's compilation unit. */ @@ -86,7 +86,7 @@ public class ClassEntry extends StructureTypeEntry { /** * A list of the same dirs. */ - private LinkedList localDirs; + private List localDirs; /** * This flag is true iff the entry includes methods that are deopt targets. */ @@ -94,14 +94,16 @@ public class ClassEntry extends StructureTypeEntry { public ClassEntry(String className, FileEntry fileEntry, int size) { super(className, size); - this.interfaces = new LinkedList<>(); + this.interfaces = new ArrayList<>(); this.fileEntry = fileEntry; + // methods is a sorted list and we want to be able to add more elements to it while keeping it sorted, + // so a LinkedList seems more appropriate than an ArrayList. (see getMethodEntry) this.methods = new LinkedList<>(); - this.primaryEntries = new LinkedList<>(); + this.primaryEntries = new ArrayList<>(); this.primaryIndex = new HashMap<>(); - this.localFiles = new LinkedList<>(); + this.localFiles = new ArrayList<>(); this.localFilesIndex = new HashMap<>(); - this.localDirs = new LinkedList<>(); + this.localDirs = new ArrayList<>(); this.localDirsIndex = new HashMap<>(); if (fileEntry != null) { localFiles.add(fileEntry); @@ -231,7 +233,7 @@ public FileEntry getFileEntry() { return fileEntry; } - public LinkedList getPrimaryEntries() { + public List getPrimaryEntries() { return primaryEntries; } @@ -240,11 +242,11 @@ public Object primaryIndexFor(Range primaryRange) { return primaryIndex.get(primaryRange); } - public LinkedList getLocalDirs() { + public List getLocalDirs() { return localDirs; } - public LinkedList getLocalFiles() { + public List getLocalFiles() { return localFiles; } diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java index 8eb7c3e5bec0..b15cd4e1860d 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java @@ -29,8 +29,9 @@ import java.nio.ByteOrder; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; import java.util.HashMap; -import java.util.LinkedList; +import java.util.List; import java.util.Map; import org.graalvm.compiler.debug.DebugContext; @@ -89,7 +90,7 @@ public abstract class DebugInfoBase { /** * List of class entries detailing class info for primary ranges. */ - private LinkedList types = new LinkedList<>(); + private List types = new ArrayList<>(); /** * index of already seen classes. */ @@ -97,7 +98,7 @@ public abstract class DebugInfoBase { /** * List of class entries detailing class info for primary ranges. */ - private LinkedList primaryClasses = new LinkedList<>(); + private List primaryClasses = new ArrayList<>(); /** * index of already seen classes. */ @@ -109,7 +110,7 @@ public abstract class DebugInfoBase { /** * List of of files which contain primary or secondary ranges. */ - private LinkedList files = new LinkedList<>(); + private List files = new ArrayList<>(); /** * Flag set to true if heap references are stored as addresses relative to a heap base register * otherwise false. @@ -426,16 +427,16 @@ public ByteOrder getByteOrder() { return byteOrder; } - public LinkedList getTypes() { + public List getTypes() { return types; } - public LinkedList getPrimaryClasses() { + public List getPrimaryClasses() { return primaryClasses; } @SuppressWarnings("unused") - public LinkedList getFiles() { + public List getFiles() { return files; } diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/InterfaceClassEntry.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/InterfaceClassEntry.java index 9b929ca6332d..9318a068b235 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/InterfaceClassEntry.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/InterfaceClassEntry.java @@ -31,7 +31,7 @@ import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugTypeInfo.DebugTypeKind; import org.graalvm.compiler.debug.DebugContext; -import java.util.LinkedList; +import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; @@ -40,7 +40,7 @@ public class InterfaceClassEntry extends ClassEntry { public InterfaceClassEntry(String className, FileEntry fileEntry, int size) { super(className, fileEntry, size); - implementors = new LinkedList<>(); + implementors = new ArrayList<>(); } @Override diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/PrimaryEntry.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/PrimaryEntry.java index 53aaa5a2b7d6..c61e3428d140 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/PrimaryEntry.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/PrimaryEntry.java @@ -28,7 +28,7 @@ import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugFrameSizeChange; -import java.util.LinkedList; +import java.util.ArrayList; import java.util.List; /** @@ -59,7 +59,7 @@ public class PrimaryEntry { public PrimaryEntry(Range primary, List frameSizeInfos, int frameSize, ClassEntry classEntry) { this.primary = primary; this.classEntry = classEntry; - this.subranges = new LinkedList<>(); + this.subranges = new ArrayList<>(); this.frameSizeInfos = frameSizeInfos; this.frameSize = frameSize; } diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/StructureTypeEntry.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/StructureTypeEntry.java index dcc80a0eb71f..d678b09029a8 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/StructureTypeEntry.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/StructureTypeEntry.java @@ -31,7 +31,7 @@ import java.lang.reflect.Modifier; import java.nio.file.Path; -import java.util.LinkedList; +import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; @@ -47,7 +47,7 @@ public abstract class StructureTypeEntry extends TypeEntry { public StructureTypeEntry(String typeName, int size) { super(typeName, size); - this.fields = new LinkedList<>(); + this.fields = new ArrayList<>(); } public Stream fields() { diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/dwarf/DwarfARangesSectionImpl.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/dwarf/DwarfARangesSectionImpl.java index 02fad181804b..e24cda20f423 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/dwarf/DwarfARangesSectionImpl.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/dwarf/DwarfARangesSectionImpl.java @@ -34,7 +34,7 @@ import com.oracle.objectfile.debugentry.Range; import org.graalvm.compiler.debug.DebugContext; -import java.util.LinkedList; +import java.util.List; import java.util.Map; /** @@ -102,7 +102,7 @@ public void createContent() { * Align to 2 * address size. */ pos += DW_AR_HEADER_PAD_SIZE; - LinkedList classPrimaryEntries = classEntry.getPrimaryEntries(); + List classPrimaryEntries = classEntry.getPrimaryEntries(); if (classEntry.includesDeoptTarget()) { /* Deopt targets are in a higher address range so delay emit for them. */ for (PrimaryEntry classPrimaryEntry : classPrimaryEntries) { @@ -123,7 +123,7 @@ public void createContent() { * Align to 2 * address size. */ pos += DW_AR_HEADER_PAD_SIZE; - LinkedList classPrimaryEntries = classEntry.getPrimaryEntries(); + List classPrimaryEntries = classEntry.getPrimaryEntries(); for (PrimaryEntry classPrimaryEntry : classPrimaryEntries) { if (classPrimaryEntry.getPrimary().isDeoptTarget()) { pos += 2 * 8; @@ -167,7 +167,7 @@ public void writeContent(DebugContext context) { int lastpos = pos; int length = DW_AR_HEADER_SIZE + DW_AR_HEADER_PAD_SIZE - 4; int cuIndex = getCUIndex(classEntry); - LinkedList classPrimaryEntries = classEntry.getPrimaryEntries(); + List classPrimaryEntries = classEntry.getPrimaryEntries(); /* * Count only real methods, omitting deopt targets. */ @@ -218,7 +218,7 @@ public void writeContent(DebugContext context) { int lastpos = pos; int length = DW_AR_HEADER_SIZE + DW_AR_HEADER_PAD_SIZE - 4; int cuIndex = getDeoptCUIndex(classEntry); - LinkedList classPrimaryEntries = classEntry.getPrimaryEntries(); + List classPrimaryEntries = classEntry.getPrimaryEntries(); /* * Count only linkage stubs. */ diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/dwarf/DwarfInfoSectionImpl.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/dwarf/DwarfInfoSectionImpl.java index 39ac113011f7..00e88b8626d7 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/dwarf/DwarfInfoSectionImpl.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/dwarf/DwarfInfoSectionImpl.java @@ -27,7 +27,7 @@ package com.oracle.objectfile.elf.dwarf; import java.lang.reflect.Modifier; -import java.util.LinkedList; +import java.util.List; import java.util.Map; import java.util.Set; @@ -439,7 +439,7 @@ private int writePrimaryClassUnit(DebugContext context, ClassEntry classEntry, b String compilationDirectory = classEntry.getCachePath(); log(context, " [0x%08x] comp_dir 0x%x (%s)", pos, debugStringIndex(compilationDirectory), compilationDirectory); pos = writeAttrStrp(compilationDirectory, buffer, pos); - LinkedList classPrimaryEntries = classEntry.getPrimaryEntries(); + List classPrimaryEntries = classEntry.getPrimaryEntries(); /* * Specify hi and lo for the compile unit which means we also need to ensure methods within * it are listed in ascending address order. @@ -654,7 +654,7 @@ private int writeField(DebugContext context, StructureTypeEntry entry, FieldEntr private int writeMethodDeclarations(DebugContext context, ClassEntry classEntry, byte[] buffer, int p) { int pos = p; - LinkedList classPrimaryEntries = classEntry.getPrimaryEntries(); + List classPrimaryEntries = classEntry.getPrimaryEntries(); for (PrimaryEntry primaryEntry : classPrimaryEntries) { Range range = primaryEntry.getPrimary(); /* @@ -913,7 +913,7 @@ private int writeInterfaceType(DebugContext context, InterfaceClassEntry interfa private int writeMethodLocations(DebugContext context, ClassEntry classEntry, byte[] buffer, int p) { int pos = p; - LinkedList classPrimaryEntries = classEntry.getPrimaryEntries(); + List classPrimaryEntries = classEntry.getPrimaryEntries(); for (PrimaryEntry primaryEntry : classPrimaryEntries) { Range range = primaryEntry.getPrimary(); if (!range.isDeoptTarget()) { @@ -1181,7 +1181,7 @@ private int writeArrayTypes(DebugContext context, ArrayTypeEntry arrayTypeEntry, private int writeDeoptMethodsCU(DebugContext context, ClassEntry classEntry, byte[] buffer, int p) { int pos = p; assert classEntry.includesDeoptTarget(); - LinkedList classPrimaryEntries = classEntry.getPrimaryEntries(); + List classPrimaryEntries = classEntry.getPrimaryEntries(); String fileName = classEntry.getFileName(); int lineIndex = getLineIndex(classEntry); int abbrevCode = (fileName.length() > 0 ? DwarfDebugInfo.DW_ABBREV_CODE_class_unit1 : DwarfDebugInfo.DW_ABBREV_CODE_class_unit2); @@ -1266,10 +1266,10 @@ private int writeCUHeader(byte[] buffer, int p) { } } - private static int findLo(LinkedList classPrimaryEntries, boolean isDeoptTargetCU) { + private static int findLo(List classPrimaryEntries, boolean isDeoptTargetCU) { if (!isDeoptTargetCU) { /* First entry is the one we want. */ - return classPrimaryEntries.getFirst().getPrimary().getLo(); + return classPrimaryEntries.get(0).getPrimary().getLo(); } else { /* Need the first entry which is a deopt target. */ for (PrimaryEntry primaryEntry : classPrimaryEntries) { @@ -1284,10 +1284,10 @@ private static int findLo(LinkedList classPrimaryEntries, boolean return 0; } - private static int findHi(LinkedList classPrimaryEntries, boolean includesDeoptTarget, boolean isDeoptTargetCU) { + private static int findHi(List classPrimaryEntries, boolean includesDeoptTarget, boolean isDeoptTargetCU) { if (isDeoptTargetCU || !includesDeoptTarget) { /* Either way the last entry is the one we want. */ - return classPrimaryEntries.getLast().getPrimary().getHi(); + return classPrimaryEntries.get(classPrimaryEntries.size() - 1).getPrimary().getHi(); } else { /* Need the last entry which is not a deopt target. */ int hi = 0;