From dbb2c7607429817e58a1a9af8012e25e861368dc Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Tue, 18 May 2021 12:55:05 +0300 Subject: [PATCH 01/11] Use method entries instead of primary ranges for method DIE generation As of https://github.com/oracle/graal/pull/3304 we associate every range with the `MethodEntry` of the method it was compiled from, and as a result we know that a `MethodEntry` exists for each compiled method in the image. Actually we create `MethodEntry`s even for methods that are not compiled but are part of `ClassEntry` that describes a Class reachable from in the image. For every range we generate a DIE (Debugging Information Entry) which references another DIE that holds the specification of the method that this range was generated from. So for every range we need a method DIE containing information for the corresponding method. Till now we have been generating these DIEs by traversing the primary ranges of each ClassEntry. There are, however, subranges that might be compiled from a method that is not referenced by a primary range, e.g., inlined methods. This patch ensures that every method that is compiled in the native image (including inlined ones) will get a method DIE. --- .../objectfile/debugentry/ClassEntry.java | 18 ++++--- .../objectfile/debugentry/DebugInfoBase.java | 6 +-- .../objectfile/debugentry/MethodEntry.java | 25 ++++++++- .../oracle/objectfile/debugentry/Range.java | 28 ++++------ .../elf/dwarf/DwarfInfoSectionImpl.java | 53 ++++++++++--------- 5 files changed, 78 insertions(+), 52 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 83322f45cc37..a4a5a5a98c31 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 @@ -140,7 +140,7 @@ 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.methods.add(this.processMethod(methodFieldInfo, debugInfoBase, debugContext))); + debugInstanceTypeInfo.methodInfoProvider().forEach(methodFieldInfo -> this.methods.add(this.processMethod(methodFieldInfo, debugInfoBase, debugContext, false))); /* Sort methods to improve lookup speed */ this.methods.sort(MethodEntry::compareTo); } @@ -275,7 +275,7 @@ private void processInterface(String interfaceName, DebugInfoBase debugInfoBase, interfaceClassEntry.addImplementor(this, debugContext); } - protected MethodEntry processMethod(DebugMethodInfo debugMethodInfo, DebugInfoBase debugInfoBase, DebugContext debugContext) { + protected MethodEntry processMethod(DebugMethodInfo debugMethodInfo, DebugInfoBase debugInfoBase, DebugContext debugContext, boolean fromRangeInfo) { String methodName = debugInfoBase.uniqueDebugString(debugMethodInfo.name()); String resultTypeName = TypeEntry.canonicalize(debugMethodInfo.valueType()); int modifiers = debugMethodInfo.modifiers(); @@ -302,7 +302,8 @@ protected MethodEntry processMethod(DebugMethodInfo debugMethodInfo, DebugInfoBa * substitution */ FileEntry methodFileEntry = debugInfoBase.ensureFileEntry(fileName, filePath, cachePath); - return new MethodEntry(methodFileEntry, methodName, this, resultType, paramTypeArray, paramNameArray, modifiers, debugMethodInfo.isDeoptTarget()); + return new MethodEntry(methodFileEntry, debugMethodInfo.symbolNameForMethod(), methodName, this, resultType, + paramTypeArray, paramNameArray, modifiers, debugMethodInfo.isDeoptTarget(), fromRangeInfo); } @Override @@ -343,13 +344,13 @@ public ClassEntry getSuperClass() { return superClass; } - public Range makePrimaryRange(String symbolName, StringTable stringTable, MethodEntry method, int lo, int hi, int primaryLine) { + public Range makePrimaryRange(StringTable stringTable, MethodEntry method, int lo, int hi, int primaryLine) { FileEntry fileEntryToUse = method.fileEntry; if (fileEntryToUse == null) { /* Last chance is the class's file entry. */ fileEntryToUse = this.fileEntry; } - return new Range(symbolName, stringTable, method, fileEntryToUse, lo, hi, primaryLine); + return new Range(stringTable, method, fileEntryToUse, lo, hi, primaryLine); } public MethodEntry getMethodEntry(DebugMethodInfo debugMethodInfo, DebugInfoBase debugInfoBase, DebugContext debugContext) { @@ -362,13 +363,14 @@ public MethodEntry getMethodEntry(DebugMethodInfo debugMethodInfo, DebugInfoBase MethodEntry methodEntry = methodIterator.next(); int comparisonResult = methodEntry.compareTo(methodName, paramSignature, returnTypeName); if (comparisonResult == 0) { + methodEntry.setInRange(); return methodEntry; } else if (comparisonResult > 0) { methodIterator.previous(); break; } } - MethodEntry newMethodEntry = processMethod(debugMethodInfo, debugInfoBase, debugContext); + MethodEntry newMethodEntry = processMethod(debugMethodInfo, debugInfoBase, debugContext, true); methodIterator.add(newMethodEntry); return newMethodEntry; } @@ -378,4 +380,8 @@ private static boolean listIsSorted(List list) { copy.sort(MethodEntry::compareTo); return list.equals(copy); } + + public List getMethods() { + return methods; + } } 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 b15cd4e1860d..57828fedd4c8 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,7 +239,6 @@ public void installDebugInfo(DebugInfoProvider debugInfoProvider) { Path filePath = debugCodeInfo.filePath(); String className = TypeEntry.canonicalize(debugCodeInfo.ownerType()); String methodName = debugCodeInfo.name(); - String symbolName = debugCodeInfo.symbolNameForMethod(); int lo = debugCodeInfo.addressLo(); int hi = debugCodeInfo.addressHi(); int primaryLine = debugCodeInfo.line(); @@ -247,7 +246,7 @@ public void installDebugInfo(DebugInfoProvider debugInfoProvider) { /* Search for a method defining this primary range. */ ClassEntry classEntry = ensureClassEntry(className); MethodEntry methodEntry = classEntry.getMethodEntry(debugCodeInfo, this, debugContext); - Range primaryRange = classEntry.makePrimaryRange(symbolName, stringTable, methodEntry, lo, hi, primaryLine); + Range primaryRange = classEntry.makePrimaryRange(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 -> { @@ -255,7 +254,6 @@ public void installDebugInfo(DebugInfoProvider debugInfoProvider) { Path filePathAtLine = debugLineInfo.filePath(); String classNameAtLine = TypeEntry.canonicalize(debugLineInfo.ownerType()); String methodNameAtLine = debugLineInfo.name(); - String symbolNameAtLine = debugLineInfo.symbolNameForMethod(); int loAtLine = lo + debugLineInfo.addressLo(); int hiAtLine = lo + debugLineInfo.addressHi(); int line = debugLineInfo.line(); @@ -265,7 +263,7 @@ public void installDebugInfo(DebugInfoProvider debugInfoProvider) { */ ClassEntry subClassEntry = ensureClassEntry(classNameAtLine); MethodEntry subMethodEntry = subClassEntry.getMethodEntry(debugLineInfo, this, debugContext); - Range subRange = new Range(symbolNameAtLine, stringTable, subMethodEntry, loAtLine, hiAtLine, line, primaryRange); + Range subRange = new Range(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/MethodEntry.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/MethodEntry.java index cca95588a76e..af38373d39ed 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 @@ -30,14 +30,21 @@ public class MethodEntry extends MemberEntry implements Comparable final TypeEntry[] paramTypes; final String[] paramNames; final boolean isDeoptTarget; + boolean isInRange; - public MethodEntry(FileEntry fileEntry, String methodName, ClassEntry ownerType, TypeEntry valueType, TypeEntry[] paramTypes, String[] paramNames, int modifiers, boolean isDeoptTarget) { + final String symbolName; + + public MethodEntry(FileEntry fileEntry, String symbolName, String methodName, ClassEntry ownerType, + TypeEntry valueType, TypeEntry[] paramTypes, String[] paramNames, int modifiers, + boolean isDeoptTarget, boolean isInRange) { 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; + this.isInRange = isInRange; + this.symbolName = symbolName; } public String methodName() { @@ -60,6 +67,10 @@ public TypeEntry getParamType(int idx) { return paramTypes[idx]; } + public TypeEntry[] getParamTypes() { + return paramTypes; + } + public String getParamTypeName(int idx) { assert paramTypes != null; assert idx < paramTypes.length; @@ -74,6 +85,18 @@ public String getParamName(int idx) { return paramNames[idx]; } + public boolean isInRange() { + return isInRange; + } + + public void setInRange() { + isInRange = true; + } + + public String getSymbolName() { + return symbolName; + } + public int compareTo(String methodName, String paramSignature, String returnTypeName) { int nameComparison = memberName.compareTo(methodName); if (nameComparison != 0) { 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 dd82d22565b1..af465363bbfc 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,8 +35,7 @@ public class Range { private static final String CLASS_DELIMITER = "."; private final FileEntry fileEntry; - private MethodEntry methodEntry; - private final String symbolName; + private final MethodEntry methodEntry; private final String fullMethodNameWithParams; private final int lo; private final int hi; @@ -49,21 +48,21 @@ public class Range { /* * Create a primary range. */ - 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); + public Range(StringTable stringTable, MethodEntry methodEntry, FileEntry fileEntry, int lo, int hi, int line) { + this(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, primary); + public Range(StringTable stringTable, MethodEntry methodEntry, int lo, int hi, int line, Range primary) { + this(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, + private Range(StringTable stringTable, MethodEntry methodEntry, FileEntry fileEntry, int lo, int hi, int line, Range primary) { this.fileEntry = fileEntry; if (fileEntry != null) { @@ -72,7 +71,6 @@ private Range(String symbolName, StringTable stringTable, MethodEntry methodEntr } assert methodEntry != null; this.methodEntry = methodEntry; - this.symbolName = stringTable.uniqueString(symbolName); this.fullMethodNameWithParams = stringTable.uniqueString(constructClassAndMethodNameWithParams()); this.lo = lo; this.hi = hi; @@ -101,7 +99,7 @@ public String getMethodName() { } public String getSymbolName() { - return symbolName; + return methodEntry.getSymbolName(); } public int getHi() { @@ -159,14 +157,6 @@ private String constructClassAndMethodNameWithParams() { return getExtendedMethodName(true, true, false); } - public String getMethodReturnTypeName() { - return methodEntry.valueType.typeName; - } - - public TypeEntry[] getParamTypes() { - return methodEntry.paramTypes; - } - public FileEntry getFileEntry() { return fileEntry; } @@ -183,4 +173,8 @@ public String toString() { public String getFileName() { return fileEntry.getFileName(); } + + public MethodEntry getMethodEntry() { + return methodEntry; + } } 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 bb734a849171..41fe324a398d 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 @@ -31,6 +31,7 @@ import java.util.Map; import java.util.Set; +import com.oracle.objectfile.debugentry.MethodEntry; import org.graalvm.compiler.debug.DebugContext; import com.oracle.objectfile.BuildDependency; @@ -654,24 +655,24 @@ private int writeField(DebugContext context, StructureTypeEntry entry, FieldEntr private int writeMethodDeclarations(DebugContext context, ClassEntry classEntry, byte[] buffer, int p) { int pos = p; - List classPrimaryEntries = classEntry.getPrimaryEntries(); - for (PrimaryEntry primaryEntry : classPrimaryEntries) { - Range range = primaryEntry.getPrimary(); - /* - * Declare all methods including deopt targets even though they are written in separate - * CUs. - */ - pos = writeMethodDeclaration(context, classEntry, range, buffer, pos); + for (MethodEntry method : classEntry.getMethods()) { + if (method.isInRange()) { + /* + * Declare all methods including deopt targets even though they are written in + * separate CUs. + */ + pos = writeMethodDeclaration(context, classEntry, method, buffer, pos); + } } return pos; } - private int writeMethodDeclaration(DebugContext context, ClassEntry classEntry, Range range, byte[] buffer, int p) { + private int writeMethodDeclaration(DebugContext context, ClassEntry classEntry, MethodEntry method, byte[] buffer, int p) { int pos = p; - String methodKey = range.getSymbolName(); + String methodKey = method.getSymbolName(); setMethodDeclarationIndex(classEntry, methodKey, pos); - int modifiers = range.getModifiers(); + int modifiers = method.getModifiers(); boolean isStatic = Modifier.isStatic(modifiers); log(context, " [0x%08x] method declaration %s", pos, methodKey); int abbrevCode = (isStatic ? DwarfDebugInfo.DW_ABBREV_CODE_method_declaration2 : DwarfDebugInfo.DW_ABBREV_CODE_method_declaration1); @@ -679,19 +680,23 @@ private int writeMethodDeclaration(DebugContext context, ClassEntry classEntry, pos = writeAbbrevCode(abbrevCode, buffer, pos); log(context, " [0x%08x] external true", pos); pos = writeFlag((byte) 1, buffer, pos); - String name = uniqueDebugString(range.getMethodName()); + String name = uniqueDebugString(method.methodName()); log(context, " [0x%08x] name 0x%x (%s)", pos, debugStringIndex(name), name); pos = writeAttrStrp(name, buffer, pos); - FileEntry fileEntry = range.getFileEntry(); - int fileIdx = (fileEntry != null ? classEntry.localFilesIdx(fileEntry) : classEntry.localFilesIdx()); - log(context, " [0x%08x] file 0x%x (%s)", pos, fileIdx, range.getFileEntry().getFullName()); + FileEntry fileEntry = method.getFileEntry(); + if (fileEntry == null) { + fileEntry = classEntry.getFileEntry(); + } + assert fileEntry != null; + int fileIdx = classEntry.localFilesIdx(fileEntry); + log(context, " [0x%08x] file 0x%x (%s)", pos, fileIdx, fileEntry.getFullName()); pos = writeAttrData2((short) fileIdx, buffer, pos); - String returnTypeName = range.getMethodReturnTypeName(); + String returnTypeName = method.getValueType().getTypeName(); int retTypeIdx = getTypeIndex(returnTypeName); log(context, " [0x%08x] type 0x%x (%s)", pos, retTypeIdx, returnTypeName); pos = writeAttrRefAddr(retTypeIdx, buffer, pos); - log(context, " [0x%08x] artificial %s", pos, range.isDeoptTarget() ? "true" : "false"); - pos = writeFlag((range.isDeoptTarget() ? (byte) 1 : (byte) 0), buffer, pos); + log(context, " [0x%08x] artificial %s", pos, method.isDeoptTarget() ? "true" : "false"); + pos = writeFlag((method.isDeoptTarget() ? (byte) 1 : (byte) 0), buffer, pos); log(context, " [0x%08x] accessibility %s", pos, "public"); pos = writeAttrAccessibility(modifiers, buffer, pos); log(context, " [0x%08x] declaration true", pos); @@ -713,22 +718,22 @@ private int writeMethodDeclaration(DebugContext context, ClassEntry classEntry, writeAttrRefAddr(pos, buffer, objectPointerIndex); } /* Write method parameter declarations. */ - pos = writeMethodParameterDeclarations(context, classEntry, range, true, buffer, pos); + pos = writeMethodParameterDeclarations(context, classEntry, method, true, buffer, pos); /* * Write a terminating null attribute. */ return writeAttrNull(buffer, pos); } - private int writeMethodParameterDeclarations(DebugContext context, ClassEntry classEntry, Range range, boolean isSpecification, byte[] buffer, int p) { + private int writeMethodParameterDeclarations(DebugContext context, ClassEntry classEntry, MethodEntry method, boolean isSpecification, byte[] buffer, int p) { int pos = p; - if (!Modifier.isStatic(range.getModifiers())) { + if (!Modifier.isStatic(method.getModifiers())) { pos = writeMethodParameterDeclaration(context, "this", classEntry.getTypeName(), true, isSpecification, buffer, pos); } - for (TypeEntry paramType : range.getParamTypes()) { + for (TypeEntry paramType : method.getParamTypes()) { String paramTypeName = paramType.getTypeName(); String paramName = uniqueDebugString(""); - FileEntry fileEntry = range.getFileEntry(); + FileEntry fileEntry = method.getFileEntry(); if (fileEntry != null) { pos = writeMethodParameterDeclaration(context, paramName, paramTypeName, false, isSpecification, buffer, pos); } else { @@ -1237,7 +1242,7 @@ private int writeMethodLocation(DebugContext context, ClassEntry classEntry, Ran int methodSpecOffset = getMethodDeclarationIndex(classEntry, methodKey); log(context, " [0x%08x] specification 0x%x (%s)", pos, methodSpecOffset, methodKey); pos = writeAttrRefAddr(methodSpecOffset, buffer, pos); - pos = writeMethodParameterDeclarations(context, classEntry, range, false, buffer, pos); + pos = writeMethodParameterDeclarations(context, classEntry, range.getMethodEntry(), false, buffer, pos); /* * Write a terminating null attribute. */ From a658b95d63a93b1980e4ac81fd4c034c70b9d9cb Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Tue, 18 May 2021 13:43:14 +0300 Subject: [PATCH 02/11] Remove FileEntry from Range, use the one from the corresponding MethodEntry --- .../objectfile/debugentry/ClassEntry.java | 14 ++------- .../objectfile/debugentry/DebugInfoBase.java | 2 +- .../oracle/objectfile/debugentry/Range.java | 30 +++++++------------ 3 files changed, 14 insertions(+), 32 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 a4a5a5a98c31..0b3117ae164c 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 @@ -157,8 +157,9 @@ public void indexPrimary(Range primary, List frameSizeInfo assert includesDeoptTarget == false; } FileEntry primaryFileEntry = primary.getFileEntry(); - assert primaryFileEntry != null; - indexLocalFileEntry(primaryFileEntry); + if (primaryFileEntry != null) { + indexLocalFileEntry(primaryFileEntry); + } } } @@ -344,15 +345,6 @@ public ClassEntry getSuperClass() { return superClass; } - public Range makePrimaryRange(StringTable stringTable, MethodEntry method, int lo, int hi, int primaryLine) { - FileEntry fileEntryToUse = method.fileEntry; - if (fileEntryToUse == null) { - /* Last chance is the class's file entry. */ - fileEntryToUse = this.fileEntry; - } - return new Range(stringTable, method, fileEntryToUse, lo, hi, primaryLine); - } - public MethodEntry getMethodEntry(DebugMethodInfo debugMethodInfo, DebugInfoBase debugInfoBase, DebugContext debugContext) { assert listIsSorted(methods); String methodName = debugInfoBase.uniqueDebugString(debugMethodInfo.name()); 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 57828fedd4c8..cac1e54dc20f 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 @@ -246,7 +246,7 @@ public void installDebugInfo(DebugInfoProvider debugInfoProvider) { /* Search for a method defining this primary range. */ ClassEntry classEntry = ensureClassEntry(className); MethodEntry methodEntry = classEntry.getMethodEntry(debugCodeInfo, this, debugContext); - Range primaryRange = classEntry.makePrimaryRange(stringTable, methodEntry, lo, hi, primaryLine); + Range primaryRange = new Range(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 af465363bbfc..5f7f3fe3bdab 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,6 @@ public class Range { private static final String CLASS_DELIMITER = "."; - private final FileEntry fileEntry; private final MethodEntry methodEntry; private final String fullMethodNameWithParams; private final int lo; @@ -48,28 +47,19 @@ public class Range { /* * Create a primary range. */ - public Range(StringTable stringTable, MethodEntry methodEntry, FileEntry fileEntry, int lo, int hi, int line) { - this(stringTable, methodEntry, fileEntry, lo, hi, line, null); - } - - /* - * Create a secondary range. - */ - public Range(StringTable stringTable, MethodEntry methodEntry, int lo, int hi, int line, Range primary) { - this(stringTable, methodEntry, methodEntry.fileEntry, lo, hi, line, primary); + public Range(StringTable stringTable, MethodEntry methodEntry, int lo, int hi, int line) { + this(stringTable, methodEntry, lo, hi, line, null); } /* * Create a primary or secondary range. */ - private Range(StringTable stringTable, MethodEntry methodEntry, FileEntry fileEntry, int lo, int hi, int line, - Range primary) { - this.fileEntry = fileEntry; - if (fileEntry != null) { - stringTable.uniqueDebugString(fileEntry.getFileName()); - stringTable.uniqueDebugString(fileEntry.getPathName()); - } + public Range(StringTable stringTable, MethodEntry methodEntry, int lo, int hi, int line, Range primary) { assert methodEntry != null; + if (methodEntry.fileEntry != null) { + stringTable.uniqueDebugString(methodEntry.fileEntry.getFileName()); + stringTable.uniqueDebugString(methodEntry.fileEntry.getPathName()); + } this.methodEntry = methodEntry; this.fullMethodNameWithParams = stringTable.uniqueString(constructClassAndMethodNameWithParams()); this.lo = lo; @@ -158,7 +148,7 @@ private String constructClassAndMethodNameWithParams() { } public FileEntry getFileEntry() { - return fileEntry; + return methodEntry.fileEntry; } public int getModifiers() { @@ -167,11 +157,11 @@ public int getModifiers() { @Override public String toString() { - return String.format("Range(lo=0x%05x hi=0x%05x %s %s:%d)", lo, hi, constructClassAndMethodNameWithParams(), fileEntry.getFullName(), line); + return String.format("Range(lo=0x%05x hi=0x%05x %s %s:%d)", lo, hi, constructClassAndMethodNameWithParams(), methodEntry.getFullFileName(), line); } public String getFileName() { - return fileEntry.getFileName(); + return methodEntry.getFileName(); } public MethodEntry getMethodEntry() { From de07631718c5693df059083ed16ebe05a3c7d12f Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Mon, 24 May 2021 16:05:35 +0300 Subject: [PATCH 03/11] Refactor: Introduce DebugRangeInfo interface --- .../oracle/objectfile/debugentry/ClassEntry.java | 14 ++++++++------ .../objectfile/debugentry/DebugInfoBase.java | 4 ++-- .../objectfile/debuginfo/DebugInfoProvider.java | 11 +++++++++-- 3 files changed, 19 insertions(+), 10 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 0b3117ae164c..f2f00374e3ba 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 @@ -40,6 +40,7 @@ import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugFrameSizeChange; import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugInstanceTypeInfo; import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugMethodInfo; +import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugRangeInfo; import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugTypeInfo; import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugTypeInfo.DebugTypeKind; @@ -99,7 +100,8 @@ public ClassEntry(String className, FileEntry fileEntry, int size) { 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) + // so a LinkedList seems more appropriate than an ArrayList. + // (see ensureMethodEntryForDebugRangeInfo) this.methods = new LinkedList<>(); this.primaryEntries = new ArrayList<>(); this.primaryIndex = new HashMap<>(); @@ -345,11 +347,11 @@ public ClassEntry getSuperClass() { return superClass; } - public MethodEntry getMethodEntry(DebugMethodInfo debugMethodInfo, DebugInfoBase debugInfoBase, DebugContext debugContext) { + public MethodEntry ensureMethodEntryForDebugRangeInfo(DebugRangeInfo debugRangeInfo, DebugInfoBase debugInfoBase, DebugContext debugContext) { assert listIsSorted(methods); - String methodName = debugInfoBase.uniqueDebugString(debugMethodInfo.name()); - String paramSignature = debugMethodInfo.paramSignature(); - String returnTypeName = debugMethodInfo.valueType(); + String methodName = debugInfoBase.uniqueDebugString(debugRangeInfo.name()); + String paramSignature = debugRangeInfo.paramSignature(); + String returnTypeName = debugRangeInfo.valueType(); ListIterator methodIterator = methods.listIterator(); while (methodIterator.hasNext()) { MethodEntry methodEntry = methodIterator.next(); @@ -362,7 +364,7 @@ public MethodEntry getMethodEntry(DebugMethodInfo debugMethodInfo, DebugInfoBase break; } } - MethodEntry newMethodEntry = processMethod(debugMethodInfo, debugInfoBase, debugContext, true); + MethodEntry newMethodEntry = processMethod(debugRangeInfo, debugInfoBase, debugContext, true); methodIterator.add(newMethodEntry); return newMethodEntry; } 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 cac1e54dc20f..c9580f47929f 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 @@ -245,7 +245,7 @@ public void installDebugInfo(DebugInfoProvider debugInfoProvider) { /* Search for a method defining this primary range. */ ClassEntry classEntry = ensureClassEntry(className); - MethodEntry methodEntry = classEntry.getMethodEntry(debugCodeInfo, this, debugContext); + MethodEntry methodEntry = classEntry.ensureMethodEntryForDebugRangeInfo(debugCodeInfo, this, debugContext); Range primaryRange = new Range(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()); @@ -262,7 +262,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.getMethodEntry(debugLineInfo, this, debugContext); + MethodEntry subMethodEntry = subClassEntry.ensureMethodEntryForDebugRangeInfo(debugLineInfo, this, debugContext); Range subRange = new Range(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/debuginfo/DebugInfoProvider.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debuginfo/DebugInfoProvider.java index 5c5729de8eb2..00ef51179038 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 @@ -227,10 +227,17 @@ interface DebugMethodInfo extends DebugMemberInfo { boolean isDeoptTarget(); } + /** + * Access details of a compiled method producing the code in a specific + * {@link com.oracle.objectfile.debugentry.Range}. + */ + interface DebugRangeInfo extends DebugMethodInfo { + } + /** * Access details of a specific compiled method. */ - interface DebugCodeInfo extends DebugMethodInfo { + interface DebugCodeInfo extends DebugRangeInfo { void debugContext(Consumer action); /** @@ -291,7 +298,7 @@ interface DebugDataInfo { * Access details of code generated for a specific outer or inlined method at a given line * number. */ - interface DebugLineInfo extends DebugMethodInfo { + interface DebugLineInfo extends DebugRangeInfo { /** * @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. From 7b7fe0e3ca008a1553da789b3e1644655dec34f0 Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Mon, 24 May 2021 23:13:19 +0300 Subject: [PATCH 04/11] Update FileEntry of MethodEntry in setInRange If the MethodEntry was added by traversing the DeclaredMethods of a Class its fileEntry will point to the original source file, thus it will be wrong for substituted methods. As a result when setting a MethodEntry as isInRange we also make sure that its fileEntry reflects the file info associated with the corresponding Range. --- .../objectfile/debugentry/ClassEntry.java | 2 +- .../objectfile/debugentry/MethodEntry.java | 20 ++++++++++++++++++- 2 files changed, 20 insertions(+), 2 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 f2f00374e3ba..d7775757797d 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 @@ -357,7 +357,7 @@ public MethodEntry ensureMethodEntryForDebugRangeInfo(DebugRangeInfo debugRangeI MethodEntry methodEntry = methodIterator.next(); int comparisonResult = methodEntry.compareTo(methodName, paramSignature, returnTypeName); if (comparisonResult == 0) { - methodEntry.setInRange(); + methodEntry.setInRange(debugInfoBase, debugRangeInfo); return methodEntry; } else if (comparisonResult > 0) { methodIterator.previous(); 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 af38373d39ed..a002ffb43542 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 @@ -26,6 +26,10 @@ package com.oracle.objectfile.debugentry; +import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugRangeInfo; + +import java.nio.file.Path; + public class MethodEntry extends MemberEntry implements Comparable { final TypeEntry[] paramTypes; final String[] paramNames; @@ -89,7 +93,21 @@ public boolean isInRange() { return isInRange; } - public void setInRange() { + public void setInRange(DebugInfoBase debugInfoBase, DebugRangeInfo debugRangeInfo) { + if (isInRange) { + assert fileEntry == debugInfoBase.ensureFileEntry(debugRangeInfo.fileName(), debugRangeInfo.filePath(), debugRangeInfo.cachePath()); + return; + } + /* + * If the MethodEntry was added by traversing the DeclaredMethods of a Class its fileEntry + * will point to the original source file, thus it will be wrong for substituted methods. As + * a result when setting a MethodEntry as isInRange we also make sure that its fileEntry + * reflects the file info associated with the corresponding Range. + */ + String fileName = debugRangeInfo.fileName(); + Path filePath = debugRangeInfo.filePath(); + Path cachePath = debugRangeInfo.cachePath(); + fileEntry = debugInfoBase.ensureFileEntry(fileName, filePath, cachePath); isInRange = true; } From 754d49a4b2a4c718559cd7a2ae73306fb34e9582 Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Tue, 25 May 2021 01:52:40 +0300 Subject: [PATCH 05/11] Refactor: DebugInfoBase.ensureFileEntry --- .../src/com/oracle/objectfile/debugentry/ClassEntry.java | 7 ++----- .../com/oracle/objectfile/debugentry/DebugInfoBase.java | 7 +++++-- .../com/oracle/objectfile/debugentry/MethodEntry.java | 9 ++------- .../oracle/objectfile/debugentry/StructureTypeEntry.java | 6 +----- 4 files changed, 10 insertions(+), 19 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 d7775757797d..6177b214c57e 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 @@ -297,14 +297,11 @@ protected MethodEntry processMethod(DebugMethodInfo debugMethodInfo, DebugInfoBa paramTypeArray[idx++] = paramType; } paramNameArray = paramNames.toArray(paramNameArray); - String fileName = debugMethodInfo.fileName(); - Path filePath = debugMethodInfo.filePath(); - Path cachePath = debugMethodInfo.cachePath(); /* * n.b. the method file may differ from the owning class file when the method is a * substitution */ - FileEntry methodFileEntry = debugInfoBase.ensureFileEntry(fileName, filePath, cachePath); + FileEntry methodFileEntry = debugInfoBase.ensureFileEntry(debugMethodInfo); return new MethodEntry(methodFileEntry, debugMethodInfo.symbolNameForMethod(), methodName, this, resultType, paramTypeArray, paramNameArray, modifiers, debugMethodInfo.isDeoptTarget(), fromRangeInfo); } @@ -349,10 +346,10 @@ public ClassEntry getSuperClass() { public MethodEntry ensureMethodEntryForDebugRangeInfo(DebugRangeInfo debugRangeInfo, DebugInfoBase debugInfoBase, DebugContext debugContext) { assert listIsSorted(methods); + ListIterator methodIterator = methods.listIterator(); String methodName = debugInfoBase.uniqueDebugString(debugRangeInfo.name()); String paramSignature = debugRangeInfo.paramSignature(); String returnTypeName = debugRangeInfo.valueType(); - ListIterator methodIterator = methods.listIterator(); while (methodIterator.hasNext()) { MethodEntry methodEntry = methodIterator.next(); int comparisonResult = methodEntry.compareTo(methodName, paramSignature, returnTypeName); 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 c9580f47929f..e328446d3b00 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 @@ -34,6 +34,7 @@ import java.util.List; import java.util.Map; +import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugFileInfo; import org.graalvm.compiler.debug.DebugContext; import com.oracle.objectfile.debuginfo.DebugInfoProvider; @@ -388,10 +389,12 @@ private FileEntry addFileEntry(String fileName, Path filePath, Path cachePath) { return fileEntry; } - protected FileEntry ensureFileEntry(String fileName, Path filePath, Path cachePath) { + protected FileEntry ensureFileEntry(DebugFileInfo debugFileInfo) { + String fileName = debugFileInfo.fileName(); if (fileName == null || fileName.length() == 0) { return null; } + Path filePath = debugFileInfo.filePath(); Path fileAsPath; if (filePath == null) { fileAsPath = Paths.get(fileName); @@ -401,7 +404,7 @@ protected FileEntry ensureFileEntry(String fileName, Path filePath, Path cachePa /* Reuse any existing entry. */ FileEntry fileEntry = findFile(fileAsPath); if (fileEntry == null) { - fileEntry = addFileEntry(fileName, filePath, cachePath); + fileEntry = addFileEntry(fileName, filePath, debugFileInfo.cachePath()); } return fileEntry; } 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 a002ffb43542..4260706e068d 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 @@ -28,8 +28,6 @@ import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugRangeInfo; -import java.nio.file.Path; - public class MethodEntry extends MemberEntry implements Comparable { final TypeEntry[] paramTypes; final String[] paramNames; @@ -95,7 +93,7 @@ public boolean isInRange() { public void setInRange(DebugInfoBase debugInfoBase, DebugRangeInfo debugRangeInfo) { if (isInRange) { - assert fileEntry == debugInfoBase.ensureFileEntry(debugRangeInfo.fileName(), debugRangeInfo.filePath(), debugRangeInfo.cachePath()); + assert fileEntry == debugInfoBase.ensureFileEntry(debugRangeInfo); return; } /* @@ -104,10 +102,7 @@ public void setInRange(DebugInfoBase debugInfoBase, DebugRangeInfo debugRangeInf * a result when setting a MethodEntry as isInRange we also make sure that its fileEntry * reflects the file info associated with the corresponding Range. */ - String fileName = debugRangeInfo.fileName(); - Path filePath = debugRangeInfo.filePath(); - Path cachePath = debugRangeInfo.cachePath(); - fileEntry = debugInfoBase.ensureFileEntry(fileName, filePath, cachePath); + fileEntry = debugInfoBase.ensureFileEntry(debugRangeInfo); isInRange = true; } 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 d678b09029a8..745e2488162e 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 @@ -30,7 +30,6 @@ import org.graalvm.compiler.debug.DebugContext; import java.lang.reflect.Modifier; -import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; @@ -68,14 +67,11 @@ protected FieldEntry addField(DebugFieldInfo debugFieldInfo, DebugInfoBase debug debugContext.log("typename %s adding %s field %s type %s size %s at offset %d\n", typeName, memberModifiers(fieldModifiers), fieldName, valueTypeName, fieldSize, fieldoffset); TypeEntry valueType = debugInfoBase.lookupTypeEntry(valueTypeName); - String fileName = debugFieldInfo.fileName(); - Path filePath = debugFieldInfo.filePath(); - Path cachePath = debugFieldInfo.cachePath(); /* * n.b. the field file may differ from the owning class file when the field is a * substitution */ - FileEntry fileEntry = debugInfoBase.ensureFileEntry(fileName, filePath, cachePath); + FileEntry fileEntry = debugInfoBase.ensureFileEntry(debugFieldInfo); FieldEntry fieldEntry = new FieldEntry(fileEntry, fieldName, this, valueType, fieldSize, fieldoffset, fieldModifiers); fields.add(fieldEntry); return fieldEntry; From 37e5cbe57d553a104e01a65c0ed2b1d0ba9c7ac9 Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Tue, 25 May 2021 01:58:18 +0300 Subject: [PATCH 06/11] Ensure fileEntry is in localFilesIndex of corresponding ClassEntry --- .../oracle/objectfile/debugentry/ClassEntry.java | 6 +++++- .../oracle/objectfile/debugentry/MethodEntry.java | 14 ++++++++++++-- 2 files changed, 17 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 6177b214c57e..1e320fcc56f3 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 @@ -354,7 +354,11 @@ public MethodEntry ensureMethodEntryForDebugRangeInfo(DebugRangeInfo debugRangeI MethodEntry methodEntry = methodIterator.next(); int comparisonResult = methodEntry.compareTo(methodName, paramSignature, returnTypeName); if (comparisonResult == 0) { - methodEntry.setInRange(debugInfoBase, debugRangeInfo); + methodEntry.setInRangeAndUpdateFileEntry(debugInfoBase, debugRangeInfo); + if (methodEntry.fileEntry != null) { + /* Ensure that the methodEntry's fileEntry is present in the localsFileIndex */ + indexLocalFileEntry(methodEntry.fileEntry); + } return methodEntry; } else if (comparisonResult > 0) { methodIterator.previous(); 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 4260706e068d..a07a0a43047e 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 @@ -91,11 +91,22 @@ public boolean isInRange() { return isInRange; } - public void setInRange(DebugInfoBase debugInfoBase, DebugRangeInfo debugRangeInfo) { + /** + * Sets {@code isInRange} and ensures that the {@code fileEntry} is up to date. If the + * MethodEntry was added by traversing the DeclaredMethods of a Class its fileEntry will point + * to the original source file, thus it will be wrong for substituted methods. As a result when + * setting a MethodEntry as isInRange we also make sure that its fileEntry reflects the file + * info associated with the corresponding Range. + * + * @param debugInfoBase + * @param debugRangeInfo + */ + public void setInRangeAndUpdateFileEntry(DebugInfoBase debugInfoBase, DebugRangeInfo debugRangeInfo) { if (isInRange) { assert fileEntry == debugInfoBase.ensureFileEntry(debugRangeInfo); return; } + isInRange = true; /* * If the MethodEntry was added by traversing the DeclaredMethods of a Class its fileEntry * will point to the original source file, thus it will be wrong for substituted methods. As @@ -103,7 +114,6 @@ public void setInRange(DebugInfoBase debugInfoBase, DebugRangeInfo debugRangeInf * reflects the file info associated with the corresponding Range. */ fileEntry = debugInfoBase.ensureFileEntry(debugRangeInfo); - isInRange = true; } public String getSymbolName() { From a53a3cec672261756b4e525bf2493cf61f0f6ad2 Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Tue, 1 Jun 2021 16:10:09 +0300 Subject: [PATCH 07/11] Refactor: Remove MethodEntry.isDeoptTarget() --- .../src/com/oracle/objectfile/debugentry/MethodEntry.java | 6 +----- .../oracle/objectfile/elf/dwarf/DwarfInfoSectionImpl.java | 4 ++-- 2 files changed, 3 insertions(+), 7 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 a07a0a43047e..c9c004cf23bd 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 @@ -31,7 +31,7 @@ public class MethodEntry extends MemberEntry implements Comparable { final TypeEntry[] paramTypes; final String[] paramNames; - final boolean isDeoptTarget; + public final boolean isDeoptTarget; boolean isInRange; final String symbolName; @@ -149,10 +149,6 @@ public int compareTo(String methodName, String paramSignature, String returnType return 0; } - public boolean isDeoptTarget() { - return isDeoptTarget; - } - @Override public int compareTo(MethodEntry other) { assert other != null; 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 41fe324a398d..58e384665f22 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 @@ -695,8 +695,8 @@ private int writeMethodDeclaration(DebugContext context, ClassEntry classEntry, int retTypeIdx = getTypeIndex(returnTypeName); log(context, " [0x%08x] type 0x%x (%s)", pos, retTypeIdx, returnTypeName); pos = writeAttrRefAddr(retTypeIdx, buffer, pos); - log(context, " [0x%08x] artificial %s", pos, method.isDeoptTarget() ? "true" : "false"); - pos = writeFlag((method.isDeoptTarget() ? (byte) 1 : (byte) 0), buffer, pos); + log(context, " [0x%08x] artificial %s", pos, method.isDeoptTarget ? "true" : "false"); + pos = writeFlag((method.isDeoptTarget ? (byte) 1 : (byte) 0), buffer, pos); log(context, " [0x%08x] accessibility %s", pos, "public"); pos = writeAttrAccessibility(modifiers, buffer, pos); log(context, " [0x%08x] declaration true", pos); From a21ba7832c3b1798470bac7a3978b8577eb856f9 Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Tue, 1 Jun 2021 16:12:26 +0300 Subject: [PATCH 08/11] Refactor: Change ClassEntry.methods from LinkedList to ArrayList I originally considered LinkedList more appropriate because despite the less efficient sort, it allows us to perform a sorted insertion in ensureMethodEntryForDebugRangeInfo() without having to shift elements. However, given that adding more methods to the ClassEntry during code processing (and thus needing sorted insertions) appears to be rare (empirically), the cost of shifting the elements might indeed be not significant, so I am chaning methods to ArrayList following Paul Woegerer's suggestion. --- .../src/com/oracle/objectfile/debugentry/ClassEntry.java | 7 +------ 1 file changed, 1 insertion(+), 6 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 1e320fcc56f3..2057fde4a297 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 @@ -29,7 +29,6 @@ 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; @@ -98,11 +97,7 @@ public ClassEntry(String className, FileEntry fileEntry, int size) { super(className, size); 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 ensureMethodEntryForDebugRangeInfo) - this.methods = new LinkedList<>(); + this.methods = new ArrayList<>(); this.primaryEntries = new ArrayList<>(); this.primaryIndex = new HashMap<>(); this.localFiles = new ArrayList<>(); From f5450b325d0adf3d666c68b2fff854c423065873 Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Wed, 9 Jun 2021 00:43:36 +0300 Subject: [PATCH 09/11] Refactor: Simplify MethodEntry::compareTo by generating signature String Note: Generating the signatures on demand and not in the constructor seems beneficial as it results in producing ~10900 signatures for the ~16600 `MethodEntry`s that we generate for the `hello.Hello` example we use in debuginfo testing. --- .../objectfile/debugentry/MethodEntry.java | 42 ++++++------------- 1 file changed, 13 insertions(+), 29 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 c9c004cf23bd..ab8471a6a348 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 @@ -28,6 +28,9 @@ import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugRangeInfo; +import java.util.Arrays; +import java.util.stream.Collectors; + public class MethodEntry extends MemberEntry implements Comparable { final TypeEntry[] paramTypes; final String[] paramNames; @@ -35,6 +38,7 @@ public class MethodEntry extends MemberEntry implements Comparable boolean isInRange; final String symbolName; + private String signature; public MethodEntry(FileEntry fileEntry, String symbolName, String methodName, ClassEntry ownerType, TypeEntry valueType, TypeEntry[] paramTypes, String[] paramNames, int modifiers, @@ -120,6 +124,13 @@ public String getSymbolName() { return symbolName; } + private String getSignature() { + if (signature == null) { + signature = Arrays.stream(paramTypes).map(TypeEntry::getTypeName).collect(Collectors.joining(", ")); + } + return signature; + } + public int compareTo(String methodName, String paramSignature, String returnTypeName) { int nameComparison = memberName.compareTo(methodName); if (nameComparison != 0) { @@ -129,24 +140,7 @@ public int compareTo(String methodName, String paramSignature, String returnType if (typeComparison != 0) { return typeComparison; } - String[] paramTypeNames = paramSignature.split((",")); - 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 < getParamCount(); i++) { - int paraComparison = getParamTypeName(i).compareTo(paramTypeNames[i].trim()); - if (paraComparison != 0) { - return paraComparison; - } - } - return 0; + return getSignature().compareTo(paramSignature); } @Override @@ -160,16 +154,6 @@ public int compareTo(MethodEntry other) { if (typeComparison != 0) { return typeComparison; } - 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 0; + return getSignature().compareTo(other.getSignature()); } } From 92743b42206c9cead7200dbc7c7d268bfbd26511 Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Tue, 22 Jun 2021 15:31:23 +0300 Subject: [PATCH 10/11] Return dummy relocation entry for non-existing symbols This allows us to work around the NPE observed in https://github.com/oracle/graal/pull/3419#issuecomment-860659784 Co-Authored-By: Simon Tooke --- .../objectfile/pecoff/PECoffRelocationTable.java | 2 +- .../pecoff/PECoffUserDefinedSection.java | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/pecoff/PECoffRelocationTable.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/pecoff/PECoffRelocationTable.java index 240664f27637..f9cdd31e701d 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/pecoff/PECoffRelocationTable.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/pecoff/PECoffRelocationTable.java @@ -58,7 +58,7 @@ interface PECoffRelocationMethod extends RelocationMethod { long toLong(); } - private static final class Entry implements RelocationRecord { + static final class Entry implements RelocationRecord { final PECoffSection section; final long offset; final PECoffRelocationMethod t; diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/pecoff/PECoffUserDefinedSection.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/pecoff/PECoffUserDefinedSection.java index 012ab237c092..ff35f850d50f 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/pecoff/PECoffUserDefinedSection.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/pecoff/PECoffUserDefinedSection.java @@ -149,7 +149,11 @@ public RelocationRecord markRelocationSite(int offset, ByteBuffer bb, ObjectFile PECoffRelocationTable rs = (PECoffRelocationTable) getOrCreateRelocationElement(useImplicitAddend); assert symbolName != null; PECoffSymtab.Entry ent = syms.getSymbol(symbolName); - assert ent != null; + if (ent == null) { + warn("attempting to mark relocation site for non-existent symbol " + symbolName); + /* Return (but do not add to entry list) dummy relocation entry. It is never used (in GraalVM CE) */ + return new PECoffRelocationTable.Entry(this, offset, PECoffMachine.getRelocation(getOwner().getMachine(), k), null, 0L); + } AssemblyBuffer sbb = new AssemblyBuffer(bb); sbb.setByteOrder(getOwner().getByteOrder()); @@ -196,4 +200,13 @@ public RelocationRecord markRelocationSite(int offset, ByteBuffer bb, ObjectFile return rs.addEntry(this, offset, PECoffMachine.getRelocation(getOwner().getMachine(), k), ent, explicitAddend); } + + /** + * Report a warning message in SVM. + * + * @param msg warning message that is printed. + */ + private static void warn(String msg) { + System.err.println("Warning: " + msg); + } } From 0bfd72224dd31438c487154c72e1fb84672107b1 Mon Sep 17 00:00:00 2001 From: Foivos Zakkak Date: Tue, 22 Jun 2021 15:41:44 +0300 Subject: [PATCH 11/11] Refactor: don't return RelocationRecord from markRelocationSite Removes the need of creating a dummy RelocationRecord to work around the NPE observed in https://github.com/oracle/graal/pull/3419#issuecomment-860659784 Co-Authored-By: Simon Tooke --- .../com/oracle/objectfile/BasicProgbitsSectionImpl.java | 9 ++++----- .../src/com/oracle/objectfile/ObjectFile.java | 5 ++--- .../src/com/oracle/objectfile/StringSectionImpl.java | 5 ++--- .../com/oracle/objectfile/elf/ELFProgbitsSection.java | 4 ++-- .../com/oracle/objectfile/elf/ELFUserDefinedSection.java | 5 ++--- .../com/oracle/objectfile/macho/MachORegularSection.java | 5 ++--- .../oracle/objectfile/macho/MachOUserDefinedSection.java | 5 +---- .../oracle/objectfile/pecoff/PECoffProgbitsSection.java | 4 ++-- .../objectfile/pecoff/PECoffUserDefinedSection.java | 8 +++----- 9 files changed, 20 insertions(+), 30 deletions(-) diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/BasicProgbitsSectionImpl.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/BasicProgbitsSectionImpl.java index 63fd09e45f9f..f0269d2e1447 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/BasicProgbitsSectionImpl.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/BasicProgbitsSectionImpl.java @@ -35,7 +35,6 @@ import com.oracle.objectfile.ObjectFile.ProgbitsSectionImpl; import com.oracle.objectfile.ObjectFile.RelocatableSectionImpl; import com.oracle.objectfile.ObjectFile.RelocationKind; -import com.oracle.objectfile.ObjectFile.RelocationRecord; import com.oracle.objectfile.ObjectFile.Section; /** @@ -114,15 +113,15 @@ public List
getElements() { } @Override - public RelocationRecord markRelocationSite(int offset, RelocationKind k, String symbolName, boolean useImplicitAddend, Long explicitAddend) { - return ((RelocatableSectionImpl) getElement()).markRelocationSite(offset, ByteBuffer.wrap(getContent()).order(getOwner().getByteOrder()), k, symbolName, useImplicitAddend, + public void markRelocationSite(int offset, RelocationKind k, String symbolName, boolean useImplicitAddend, Long explicitAddend) { + ((RelocatableSectionImpl) getElement()).markRelocationSite(offset, ByteBuffer.wrap(getContent()).order(getOwner().getByteOrder()), k, symbolName, useImplicitAddend, explicitAddend); } @Override - public final RelocationRecord markRelocationSite(int offset, ByteBuffer bb, RelocationKind k, String symbolName, boolean useImplicitAddend, Long explicitAddend) { + public final void markRelocationSite(int offset, ByteBuffer bb, RelocationKind k, String symbolName, boolean useImplicitAddend, Long explicitAddend) { assert getContent() == null || bb.array() == getContent(); - return ((RelocatableSectionImpl) getElement()).markRelocationSite(offset, bb, k, symbolName, useImplicitAddend, explicitAddend); + ((RelocatableSectionImpl) getElement()).markRelocationSite(offset, bb, k, symbolName, useImplicitAddend, explicitAddend); } @Override diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/ObjectFile.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/ObjectFile.java index 405ab85e41eb..9a5e7824b0fd 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/ObjectFile.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/ObjectFile.java @@ -408,9 +408,8 @@ public interface RelocatableSectionImpl extends ElementImpl { * bytes * @param useImplicitAddend whether the current bytes are to be used as an addend * @param explicitAddend a full-width addend, or null if useImplicitAddend is true - * @return the relocation record created (or found, if it exists already) */ - RelocationRecord markRelocationSite(int offset, ByteBuffer bb, RelocationKind k, String symbolName, boolean useImplicitAddend, Long explicitAddend); + void markRelocationSite(int offset, ByteBuffer bb, RelocationKind k, String symbolName, boolean useImplicitAddend, Long explicitAddend); /** * Force the creation of a relocation section/element for this section, and return it. This @@ -441,7 +440,7 @@ public interface ProgbitsSectionImpl extends RelocatableSectionImpl { * passed a buffer. It uses the byte array accessed by {@link #getContent} and * {@link #setContent}. */ - RelocationRecord markRelocationSite(int offset, RelocationKind k, String symbolName, boolean useImplicitAddend, Long explicitAddend); + void markRelocationSite(int offset, RelocationKind k, String symbolName, boolean useImplicitAddend, Long explicitAddend); } public interface NobitsSectionImpl extends ElementImpl { diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/StringSectionImpl.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/StringSectionImpl.java index 17295b31f6e0..fc262713ac3a 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/StringSectionImpl.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/StringSectionImpl.java @@ -35,7 +35,6 @@ import com.oracle.objectfile.ObjectFile.Element; import com.oracle.objectfile.ObjectFile.ProgbitsSectionImpl; import com.oracle.objectfile.ObjectFile.RelocationKind; -import com.oracle.objectfile.ObjectFile.RelocationRecord; import com.oracle.objectfile.io.AssemblyBuffer; import com.oracle.objectfile.io.OutputAssembler; @@ -125,12 +124,12 @@ public Element getOrCreateRelocationElement(boolean useImplicitAddend) { } @Override - public RelocationRecord markRelocationSite(int offset, RelocationKind k, String symbolName, boolean useImplicitAddend, Long explicitAddend) { + public void markRelocationSite(int offset, RelocationKind k, String symbolName, boolean useImplicitAddend, Long explicitAddend) { throw new UnsupportedOperationException("can't mark relocaction sites in string section"); } @Override - public RelocationRecord markRelocationSite(int offset, ByteBuffer bb, RelocationKind k, String symbolName, boolean useImplicitAddend, Long explicitAddend) { + public void markRelocationSite(int offset, ByteBuffer bb, RelocationKind k, String symbolName, boolean useImplicitAddend, Long explicitAddend) { throw new UnsupportedOperationException("can't mark relocaction sites in string section"); } diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/ELFProgbitsSection.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/ELFProgbitsSection.java index 4d36d6daf7b9..c08176850a51 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/ELFProgbitsSection.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/ELFProgbitsSection.java @@ -69,7 +69,7 @@ public void setContent(byte[] c) { } @Override - public ObjectFile.RelocationRecord markRelocationSite(int offset, ObjectFile.RelocationKind k, String symbolName, boolean useImplicitAddend, Long explicitAddend) { - return markRelocationSite(offset, ByteBuffer.wrap(getContent()).order(getOwner().getByteOrder()), k, symbolName, useImplicitAddend, explicitAddend); + public void markRelocationSite(int offset, ObjectFile.RelocationKind k, String symbolName, boolean useImplicitAddend, Long explicitAddend) { + markRelocationSite(offset, ByteBuffer.wrap(getContent()).order(getOwner().getByteOrder()), k, symbolName, useImplicitAddend, explicitAddend); } } diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/ELFUserDefinedSection.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/ELFUserDefinedSection.java index a1019b5d64fb..6d3f29be036b 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/ELFUserDefinedSection.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/ELFUserDefinedSection.java @@ -34,7 +34,6 @@ import com.oracle.objectfile.LayoutDecisionMap; import com.oracle.objectfile.ObjectFile; import com.oracle.objectfile.ObjectFile.Element; -import com.oracle.objectfile.ObjectFile.RelocationRecord; import com.oracle.objectfile.elf.ELFObjectFile.ELFSection; import com.oracle.objectfile.elf.ELFObjectFile.ELFSectionFlag; import com.oracle.objectfile.elf.ELFObjectFile.SectionType; @@ -148,7 +147,7 @@ public Element getOrCreateRelocationElement(boolean useImplicitAddend) { } @Override - public RelocationRecord markRelocationSite(int offset, ByteBuffer bb, ObjectFile.RelocationKind k, String symbolName, boolean useImplicitAddend, Long explicitAddend) { + public void markRelocationSite(int offset, ByteBuffer bb, ObjectFile.RelocationKind k, String symbolName, boolean useImplicitAddend, Long explicitAddend) { if (useImplicitAddend != (explicitAddend == null)) { throw new IllegalArgumentException("must have either an explicit or implicit addend"); } @@ -157,6 +156,6 @@ public RelocationRecord markRelocationSite(int offset, ByteBuffer bb, ObjectFile assert symbolName != null; ELFSymtab.Entry ent = syms.getSymbol(symbolName); assert ent != null; - return rs.addEntry(this, offset, ELFMachine.getRelocation(getOwner().getMachine(), k), ent, explicitAddend); + rs.addEntry(this, offset, ELFMachine.getRelocation(getOwner().getMachine(), k), ent, explicitAddend); } } diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/macho/MachORegularSection.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/macho/MachORegularSection.java index 8da0fadaf654..791c4e0f5f55 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/macho/MachORegularSection.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/macho/MachORegularSection.java @@ -30,7 +30,6 @@ import com.oracle.objectfile.ObjectFile; import com.oracle.objectfile.ObjectFile.ProgbitsSectionImpl; import com.oracle.objectfile.ObjectFile.RelocationKind; -import com.oracle.objectfile.ObjectFile.RelocationRecord; import com.oracle.objectfile.macho.MachOObjectFile.SectionFlag; import com.oracle.objectfile.macho.MachOObjectFile.Segment64Command; @@ -51,8 +50,8 @@ public byte[] getContent() { } @Override - public RelocationRecord markRelocationSite(int offset, RelocationKind k, String symbolName, boolean useImplicitAddend, Long explicitAddend) { - return markRelocationSite(offset, ByteBuffer.wrap(getContent()).order(getOwner().getByteOrder()), k, symbolName, useImplicitAddend, explicitAddend); + public void markRelocationSite(int offset, RelocationKind k, String symbolName, boolean useImplicitAddend, Long explicitAddend) { + markRelocationSite(offset, ByteBuffer.wrap(getContent()).order(getOwner().getByteOrder()), k, symbolName, useImplicitAddend, explicitAddend); } } diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/macho/MachOUserDefinedSection.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/macho/MachOUserDefinedSection.java index ceaee5d8a451..8a98f5e8448f 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/macho/MachOUserDefinedSection.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/macho/MachOUserDefinedSection.java @@ -36,7 +36,6 @@ import com.oracle.objectfile.ObjectFile; import com.oracle.objectfile.ObjectFile.Element; import com.oracle.objectfile.ObjectFile.RelocationKind; -import com.oracle.objectfile.ObjectFile.RelocationRecord; import com.oracle.objectfile.ObjectFile.Segment; import com.oracle.objectfile.ObjectFile.Symbol; import com.oracle.objectfile.io.AssemblyBuffer; @@ -160,7 +159,7 @@ public MachORelocationElement getOrCreateRelocationElement(boolean useImplicitAd } @Override - public RelocationRecord markRelocationSite(int offset, ByteBuffer bb, RelocationKind k, String symbolName, boolean useImplicitAddend, Long explicitAddend) { + public void markRelocationSite(int offset, ByteBuffer bb, RelocationKind k, String symbolName, boolean useImplicitAddend, Long explicitAddend) { MachORelocationElement el = getOrCreateRelocationElement(useImplicitAddend); AssemblyBuffer sbb = new AssemblyBuffer(bb); sbb.setByteOrder(getOwner().getByteOrder()); @@ -215,7 +214,5 @@ public RelocationRecord markRelocationSite(int offset, ByteBuffer bb, Relocation sbb.pop(); RelocationInfo rec = new RelocationInfo(el, this, offset, length, k, symbolName, createAsLocalReloc); el.add(rec); - - return rec; } } diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/pecoff/PECoffProgbitsSection.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/pecoff/PECoffProgbitsSection.java index 21e1d90481d1..5bb4740dbeb7 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/pecoff/PECoffProgbitsSection.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/pecoff/PECoffProgbitsSection.java @@ -69,7 +69,7 @@ public void setContent(byte[] c) { } @Override - public ObjectFile.RelocationRecord markRelocationSite(int offset, ObjectFile.RelocationKind k, String symbolName, boolean useImplicitAddend, Long explicitAddend) { - return markRelocationSite(offset, ByteBuffer.wrap(getContent()).order(getOwner().getByteOrder()), k, symbolName, useImplicitAddend, explicitAddend); + public void markRelocationSite(int offset, ObjectFile.RelocationKind k, String symbolName, boolean useImplicitAddend, Long explicitAddend) { + markRelocationSite(offset, ByteBuffer.wrap(getContent()).order(getOwner().getByteOrder()), k, symbolName, useImplicitAddend, explicitAddend); } } diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/pecoff/PECoffUserDefinedSection.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/pecoff/PECoffUserDefinedSection.java index ff35f850d50f..7ffcc1d003e1 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/pecoff/PECoffUserDefinedSection.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/pecoff/PECoffUserDefinedSection.java @@ -34,7 +34,6 @@ import com.oracle.objectfile.LayoutDecisionMap; import com.oracle.objectfile.ObjectFile; import com.oracle.objectfile.ObjectFile.Element; -import com.oracle.objectfile.ObjectFile.RelocationRecord; import com.oracle.objectfile.io.AssemblyBuffer; import com.oracle.objectfile.pecoff.PECoffObjectFile.PECoffSection; import com.oracle.objectfile.pecoff.PECoffObjectFile.PECoffSectionFlag; @@ -141,7 +140,7 @@ public Element getOrCreateRelocationElement(boolean useImplicitAddend) { } @Override - public RelocationRecord markRelocationSite(int offset, ByteBuffer bb, ObjectFile.RelocationKind k, String symbolName, boolean useImplicitAddend, Long explicitAddend) { + public void markRelocationSite(int offset, ByteBuffer bb, ObjectFile.RelocationKind k, String symbolName, boolean useImplicitAddend, Long explicitAddend) { if (useImplicitAddend != (explicitAddend == null)) { throw new IllegalArgumentException("must have either an explicit or implicit addend"); } @@ -151,8 +150,7 @@ public RelocationRecord markRelocationSite(int offset, ByteBuffer bb, ObjectFile PECoffSymtab.Entry ent = syms.getSymbol(symbolName); if (ent == null) { warn("attempting to mark relocation site for non-existent symbol " + symbolName); - /* Return (but do not add to entry list) dummy relocation entry. It is never used (in GraalVM CE) */ - return new PECoffRelocationTable.Entry(this, offset, PECoffMachine.getRelocation(getOwner().getMachine(), k), null, 0L); + return; } AssemblyBuffer sbb = new AssemblyBuffer(bb); @@ -198,7 +196,7 @@ public RelocationRecord markRelocationSite(int offset, ByteBuffer bb, ObjectFile // return ByteBuffer cursor to where it was sbb.pop(); - return rs.addEntry(this, offset, PECoffMachine.getRelocation(getOwner().getMachine(), k), ent, explicitAddend); + rs.addEntry(this, offset, PECoffMachine.getRelocation(getOwner().getMachine(), k), ent, explicitAddend); } /**