Skip to content

Commit fcb4ce9

Browse files
committed
[GR-59171] Use signature hash for storing @BasedOnJDKFile infos to disk
PullRequest: graal/19629
2 parents c41ce68 + 0e29436 commit fcb4ce9

File tree

7 files changed

+88
-17
lines changed

7 files changed

+88
-17
lines changed

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/attach/AttachListenerThread.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
* A dedicated listener thread that accepts client connections and that handles diagnostic command
4545
* requests. At the moment, only jcmd is supported.
4646
*/
47-
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-24+18/src/hotspot/share/services/attachListener.cpp#L453-L467")
4847
public abstract class AttachListenerThread extends Thread {
4948
private static final String JCMD_COMMAND_STRING = "jcmd";
5049
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-24+18/src/hotspot/share/services/attachListener.hpp#L142") //
@@ -55,7 +54,7 @@ public abstract class AttachListenerThread extends Thread {
5554
protected static final int ARG_COUNT_MAX = 3;
5655

5756
@SuppressWarnings("this-escape")
58-
// This constructor should be annotated with @BasedOnJDK instead of the class, see GR-59171.
57+
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-24+18/src/hotspot/share/services/attachListener.cpp#L453-L467")
5958
public AttachListenerThread() {
6059
super(PlatformThreads.singleton().systemGroup, "Attach Listener");
6160
this.setDaemon(true);

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/dcmd/JfrCheckDCmd.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,9 @@
3535
import com.oracle.svm.core.jfr.Target_jdk_jfr_internal_dcmd_AbstractDCmd;
3636
import com.oracle.svm.core.util.BasedOnJDKFile;
3737

38-
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-24+18/src/hotspot/share/jfr/dcmd/jfrDcmds.hpp#L106-L108")
3938
public class JfrCheckDCmd extends AbstractJfrDCmd {
40-
// This constructor should be annotated with @BasedOnJDK instead of the class, see GR-59171.
4139
@Platforms(Platform.HOSTED_ONLY.class)
40+
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-24+18/src/hotspot/share/jfr/dcmd/jfrDcmds.hpp#L106-L108")
4241
public JfrCheckDCmd() {
4342
super("JFR.check", "Checks running JFR recording(s)", Impact.Low);
4443
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/dcmd/JfrDumpDCmd.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,9 @@
3535
import com.oracle.svm.core.jfr.Target_jdk_jfr_internal_dcmd_AbstractDCmd;
3636
import com.oracle.svm.core.util.BasedOnJDKFile;
3737

38-
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-24+18/src/hotspot/share/jfr/dcmd/jfrDcmds.hpp#L81-L83")
3938
public class JfrDumpDCmd extends AbstractJfrDCmd {
40-
// This constructor should be annotated with @BasedOnJDK instead of the class, see GR-59171.
4139
@Platforms(Platform.HOSTED_ONLY.class)
40+
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-24+18/src/hotspot/share/jfr/dcmd/jfrDcmds.hpp#L81-L83")
4241
public JfrDumpDCmd() {
4342
super("JFR.dump", "Copies contents of a JFR recording to file. Either the name or the recording id must be specified.", Impact.Medium);
4443
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/dcmd/JfrStartDCmd.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,9 @@
3434
import com.oracle.svm.core.jfr.Target_jdk_jfr_internal_dcmd_DCmdStart;
3535
import com.oracle.svm.core.util.BasedOnJDKFile;
3636

37-
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-24+18/src/hotspot/share/jfr/dcmd/jfrDcmds.hpp#L56-L58")
3837
public class JfrStartDCmd extends AbstractJfrDCmd {
39-
// This constructor should be annotated with @BasedOnJDK instead of the class, see GR-59171.
4038
@Platforms(Platform.HOSTED_ONLY.class)
39+
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-24+18/src/hotspot/share/jfr/dcmd/jfrDcmds.hpp#L56-L58")
4140
public JfrStartDCmd() {
4241
super("JFR.start", "Starts a new JFR recording.", Impact.Medium);
4342
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/dcmd/JfrStopDCmd.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,9 @@
3535
import com.oracle.svm.core.jfr.Target_jdk_jfr_internal_dcmd_AbstractDCmd;
3636
import com.oracle.svm.core.util.BasedOnJDKFile;
3737

38-
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-24+18/src/hotspot/share/jfr/dcmd/jfrDcmds.hpp#L131-L133")
3938
public class JfrStopDCmd extends AbstractJfrDCmd {
40-
// This constructor should be annotated with @BasedOnJDK instead of the class, see GR-59171.
4139
@Platforms(Platform.HOSTED_ONLY.class)
40+
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-24+18/src/hotspot/share/jfr/dcmd/jfrDcmds.hpp#L131-L133")
4241
public JfrStopDCmd() {
4342
super("JFR.stop", "Stops a JFR recording.", Impact.Low);
4443
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/dcmd/VMNativeMemoryDCmd.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,14 @@
3232
import com.oracle.svm.core.nmt.NativeMemoryTracking;
3333
import com.oracle.svm.core.util.BasedOnJDKFile;
3434

35-
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-24+18/src/hotspot/share/nmt/nmtDCmd.hpp#L49-L52")
36-
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-24+18/src/hotspot/share/nmt/nmtDCmd.cpp#L34-L64")
3735
public class VMNativeMemoryDCmd extends AbstractDCmd {
3836
private static final DCmdOption<Boolean> SUMMARY = new DCmdOption<>(Boolean.class, "summary",
3937
"Request runtime to report current memory summary, which includes total reserved and committed memory, along with memory usage summary by each subsystem.",
4038
false, false);
4139

42-
// This constructor should be annotated with @BasedOnJDK instead of the class, see GR-59171.
4340
@Platforms(Platform.HOSTED_ONLY.class)
41+
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-24+18/src/hotspot/share/nmt/nmtDCmd.hpp#L49-L52")
42+
@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-24+18/src/hotspot/share/nmt/nmtDCmd.cpp#L34-L64")
4443
public VMNativeMemoryDCmd() {
4544
super("VM.native_memory", "Print native memory usage", Impact.Low, new DCmdOption<?>[0], new DCmdOption<?>[]{SUMMARY},
4645
new String[]{"$ jcmd <pid> VM.native_memory summary"});

substratevm/src/com.oracle.svm.processor/src/com/oracle/svm/processor/BasedOnJDKFileProcessor.java

Lines changed: 81 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
import java.io.PrintWriter;
3434
import java.net.URLEncoder;
3535
import java.nio.charset.StandardCharsets;
36+
import java.security.MessageDigest;
37+
import java.security.NoSuchAlgorithmException;
3638
import java.util.HashSet;
3739
import java.util.List;
3840
import java.util.Objects;
@@ -50,6 +52,8 @@
5052
import javax.lang.model.element.PackageElement;
5153
import javax.lang.model.element.TypeElement;
5254
import javax.lang.model.element.VariableElement;
55+
import javax.lang.model.type.ArrayType;
56+
import javax.lang.model.type.TypeMirror;
5357
import javax.tools.Diagnostic.Kind;
5458
import javax.tools.FileObject;
5559
import javax.tools.StandardLocation;
@@ -135,10 +139,14 @@ private void processAnnotation(Element annotatedElement, AnnotationMirror annota
135139
return;
136140
}
137141

138-
String qualifiedName = getQualifiedName(annotatedElement);
142+
String qualifiedShortName = getQualifiedName(annotatedElement);
143+
String qualifiedSignature = getQualifiedSignature(annotatedElement);
144+
String simpleName = getSimpleName(annotatedElement);
145+
String qualifiedName = qualifiedShortName + qualifiedSignature;
146+
String qualifiedNameHash = byteArrayToHexString(sha256encode(qualifiedName));
139147

140148
Element[] originatingElements = new Element[]{annotatedElement};
141-
String uniqueName = getUniqueName(qualifiedName, targetSourceInfo.committish, targetSourceInfo.path, targetSourceInfo.lineStart, targetSourceInfo.lineEnd);
149+
String uniqueName = getUniqueName(qualifiedName, qualifiedNameHash, simpleName, targetSourceInfo.committish, targetSourceInfo.path, targetSourceInfo.lineStart, targetSourceInfo.lineEnd);
142150

143151
String filename = "jdk_source_info/" + URLEncoder.encode(uniqueName, StandardCharsets.UTF_8) + ".json";
144152
SourceInfo annotatedSourceInfo = getAnnotatedSourceInfo(annotatedElement);
@@ -164,6 +172,23 @@ private void processAnnotation(Element annotatedElement, AnnotationMirror annota
164172
}
165173
}
166174

175+
private static byte[] sha256encode(String text) {
176+
try {
177+
MessageDigest digest = MessageDigest.getInstance("SHA-256");
178+
return digest.digest(text.getBytes(StandardCharsets.UTF_8));
179+
} catch (NoSuchAlgorithmException e) {
180+
throw new RuntimeException(e);
181+
}
182+
}
183+
184+
private static String byteArrayToHexString(byte[] a) {
185+
StringBuilder sb = new StringBuilder(a.length * 2);
186+
for (byte b : a) {
187+
sb.append(String.format("%02x", b));
188+
}
189+
return sb.toString();
190+
}
191+
167192
private static String getQualifiedName(Element annotatedElement) {
168193
if (annotatedElement instanceof TypeElement typeElement) {
169194
return typeElement.getQualifiedName().toString();
@@ -182,6 +207,52 @@ private static String getQualifiedName(Element annotatedElement) {
182207
throw new RuntimeException("Unexpected element class: " + annotatedElement.getClass().getSimpleName());
183208
}
184209

210+
private static String getSimpleName(Element annotatedElement) {
211+
if (annotatedElement instanceof ExecutableElement executableElement) {
212+
TypeElement enclosingElement = (TypeElement) executableElement.getEnclosingElement();
213+
String simpleName = executableElement.getSimpleName().toString();
214+
if ("<init>".equals(simpleName)) {
215+
// constructor
216+
return enclosingElement.getSimpleName().toString();
217+
}
218+
return enclosingElement.getSimpleName().toString() + "#" + simpleName;
219+
}
220+
return null;
221+
}
222+
223+
private static String getQualifiedSignature(Element annotatedElement) {
224+
if (annotatedElement instanceof ExecutableElement executableElement) {
225+
return getMethodDescriptor(executableElement);
226+
}
227+
return "";
228+
}
229+
230+
private static String getDescriptorForClass(TypeMirror c) {
231+
return switch (c.getKind()) {
232+
case BOOLEAN -> "Z";
233+
case BYTE -> "B";
234+
case CHAR -> "C";
235+
case SHORT -> "S";
236+
case INT -> "I";
237+
case LONG -> "J";
238+
case FLOAT -> "F";
239+
case DOUBLE -> "D";
240+
case VOID -> "V";
241+
case ARRAY -> "[" + getDescriptorForClass(((ArrayType) c).getComponentType());
242+
case DECLARED -> "L" + c.toString().replace('.', '/') + ";";
243+
default -> throw new RuntimeException("Unexpected null type: " + c);
244+
};
245+
}
246+
247+
private static String getMethodDescriptor(ExecutableElement m) {
248+
String s = "(";
249+
for (var parameter : m.getParameters()) {
250+
s += getDescriptorForClass(parameter.asType());
251+
}
252+
s += ')';
253+
return s + getDescriptorForClass(m.getReturnType());
254+
}
255+
185256
private SourceInfo parseBasedOnJDKFileAnnotation(String annotationValue) {
186257
Matcher blobMatcher = BLOB_PATTERN.matcher(annotationValue);
187258
if (blobMatcher.matches()) {
@@ -228,9 +299,15 @@ private SourceInfo getAnnotatedSourceInfo(Element annotatedElement) {
228299
return new SourceInfo(null, sourceFileName, lineMap.getLineNumber(start), lineMap.getLineNumber(end));
229300
}
230301

231-
private static String getUniqueName(String qualifiedName, String committish, String path, long lineStart, long lineEnd) {
302+
private static String getUniqueName(String qualifiedName, String qualifiedNameHash, String simpleName, String committish, String path, long lineStart, long lineEnd) {
232303
String strippedPath = path.charAt(path.length() - 1) == '/' ? path.substring(0, path.length() - 1) : path;
233-
return String.format("%s/%s/%s-%s/%s", committish, strippedPath, lineStart, lineEnd, qualifiedName);
304+
if (simpleName == null) {
305+
// packages, classes
306+
return String.format("%s/%s/%s-%s/%s", committish, strippedPath, lineStart, lineEnd, qualifiedName);
307+
} else {
308+
// methods, ctors
309+
return String.format("%s/%s/%s-%s/%s_%s", committish, strippedPath, lineStart, lineEnd, simpleName, qualifiedNameHash);
310+
}
234311
}
235312

236313
private static void printSourceInfo(PrintWriter writer, SourceInfo annotatedSourceInfo, String indent) {

0 commit comments

Comments
 (0)