Skip to content

Commit e39f6e8

Browse files
committed
svm: migrate diagnosticsagent to ClassFile API
1 parent 4e1fb0b commit e39f6e8

File tree

3 files changed

+56
-141
lines changed

3 files changed

+56
-141
lines changed

substratevm/mx.substratevm/suite.py

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -39,27 +39,6 @@
3939
},
4040

4141
"libraries" : {
42-
"ASM_9.7.1" : {
43-
"digest" : "sha512:4767b01603dad5c79cc1e2b5f3722f72b1059d928f184f446ba11badeb1b381b3a3a9a801cc43d25d396df950b09d19597c73173c411b1da890de808b94f1f50",
44-
"sourceDigest" : "sha512:d7c0de5912d04949a3d06cad366ff35a877da2682d9c74579625d62686032ea9349aff6102b17f92e9ec7eb4e9b1cd906b649c6a3ac798bfb9e31e5425de009d",
45-
"maven" : {
46-
"groupId" : "org.ow2.asm",
47-
"artifactId" : "asm",
48-
"version" : "9.7.1",
49-
},
50-
"license" : "BSD-new",
51-
},
52-
"ASM_TREE_9.7.1" : {
53-
"digest" : "sha512:e55008c392fdd35e95d3404766b12dd4b46e13d5c362fcd0ab42a65751a82737eaf0ebc857691d1916190d34407adfde4437615d69c278785416fd911e00978d",
54-
"sourceDigest" : "sha512:3cea80bc7b55679dfa3d2065c6cb6951007cc7817082e9fcf4c5e3cdc073c22eddf7c7899cff60b1092049ec9038e8d3aa9a8828ef731739bda8b5afcec30e86",
55-
"maven" : {
56-
"groupId" : "org.ow2.asm",
57-
"artifactId" : "asm-tree",
58-
"version" : "9.7.1",
59-
},
60-
"dependencies" : ["ASM_9.7.1"],
61-
"license" : "BSD-new",
62-
},
6342
"RENAISSANCE_HARNESS_v0.9" : {
6443
"urls" : ["https://lafo.ssw.uni-linz.ac.at/pub/graal-external-deps/renaissance/renaissance-harness_v0.9.0.tar.gz"],
6544
"digest" : "sha512:068207adf6bbd0a934429f7d6ddba8810e55992d06e131479658a7933bb352ea892d4304f745806dc342a6f7187a434ff2f106c6f8a6ee35ee696ea4fc998f7b",
@@ -306,36 +285,6 @@
306285
"graalCompilerSourceEdition": "ignore",
307286
},
308287

309-
# This shaded ASM project is just a quickfix.
310-
# Eventually, we should migrate to the Classfile API [JDK-8294982] (GR-61102).
311-
"com.oracle.svm.shaded.org.objectweb.asm": {
312-
# Shadowed ASM libraries (org.ow2.asm:asm,asm-tree)
313-
"subDir" : "src",
314-
"sourceDirs" : ["src"],
315-
"javaCompliance" : "17+",
316-
"spotbugsIgnoresGenerated" : True,
317-
"shadedDependencies" : [
318-
"ASM_9.7.1",
319-
"ASM_TREE_9.7.1",
320-
],
321-
"class" : "ShadedLibraryProject",
322-
"shade" : {
323-
"packages" : {
324-
"org.objectweb.asm" : "com.oracle.svm.shaded.org.objectweb.asm",
325-
},
326-
"exclude" : [
327-
"META-INF/MANIFEST.MF",
328-
"**/package.html",
329-
],
330-
},
331-
"description" : "ASM library shadowed for Native Iamge.",
332-
# We need to force javac because the generated sources in this project produce warnings in JDT.
333-
"forceJavac" : "true",
334-
"javac.lint.overrides" : "none",
335-
"jacoco" : "exclude",
336-
"graalCompilerSourceEdition": "ignore",
337-
},
338-
339288
"com.oracle.svm.processor" : {
340289
"subDir" : "src",
341290
"sourceDirs" : ["src"],
@@ -360,7 +309,6 @@
360309
],
361310
"dependencies": [
362311
"com.oracle.svm.common",
363-
"com.oracle.svm.shaded.org.objectweb.asm",
364312
"com.oracle.objectfile",
365313
"SVM_CONFIGURE",
366314
"espresso-shared:ESPRESSO_SVM",

substratevm/src/com.oracle.svm.diagnosticsagent/src/com/oracle/svm/diagnosticsagent/ClinitGenerationVisitor.java

Lines changed: 0 additions & 70 deletions
This file was deleted.

substratevm/src/com.oracle.svm.diagnosticsagent/src/com/oracle/svm/diagnosticsagent/NativeImageDiagnosticsAgent.java

Lines changed: 56 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,16 @@
2828
import static com.oracle.svm.jvmtiagentbase.Support.check;
2929
import static com.oracle.svm.jvmtiagentbase.Support.jvmtiFunctions;
3030
import static com.oracle.svm.jvmtiagentbase.jvmti.JvmtiEvent.JVMTI_EVENT_CLASS_FILE_LOAD_HOOK;
31-
31+
import static java.lang.classfile.ClassFile.ACC_PUBLIC;
32+
33+
import java.io.Serial;
34+
import java.lang.classfile.ClassBuilder;
35+
import java.lang.classfile.ClassElement;
36+
import java.lang.classfile.ClassFile;
37+
import java.lang.classfile.ClassModel;
38+
import java.lang.classfile.ClassTransform;
39+
import java.lang.classfile.MethodModel;
40+
import java.lang.constant.ConstantDescs;
3241
import java.util.ArrayList;
3342
import java.util.List;
3443
import java.util.Map;
@@ -65,8 +74,6 @@
6574
import com.oracle.svm.jvmtiagentbase.jvmti.JvmtiEventCallbacks;
6675
import com.oracle.svm.jvmtiagentbase.jvmti.JvmtiEventMode;
6776
import com.oracle.svm.jvmtiagentbase.jvmti.JvmtiInterface;
68-
import com.oracle.svm.shaded.org.objectweb.asm.ClassReader;
69-
import com.oracle.svm.shaded.org.objectweb.asm.ClassWriter;
7077

7178
/**
7279
* JVMTI agent that provides diagnostics information that helps resolve native-image build failures.
@@ -380,25 +387,13 @@ private static void onClassFileLoadHook(@SuppressWarnings("unused") JvmtiEnv jvm
380387
newClassDataLen.write(newClassDataLength);
381388
}
382389

383-
static final int ASM8 = 8 << 16;
384-
static final int ASM_TARGET_VERSION = ASM8;
385-
386390
private byte[] maybeInstrumentClassWithClinit(String clazzName, byte[] clazzData) {
387-
if (clazzName != null && !advisor.shouldTraceClassInitialization(clazzName.replace('/', '.'))) {
388-
return null;
389-
}
390-
391391
try {
392-
ClassReader reader = new ClassReader(clazzData);
393-
ClassWriter writer = new ClassWriter(reader, 0);
394-
ClinitGenerationVisitor visitor = new ClinitGenerationVisitor(ASM_TARGET_VERSION, writer);
395-
reader.accept(visitor, 0);
396-
397-
if (!visitor.didGeneration()) {
398-
return null;
392+
TracingAdvisor advisor = JvmtiAgentBase.<NativeImageDiagnosticsAgentJNIHandleSet, NativeImageDiagnosticsAgent> singleton().advisor;
393+
if (advisor.shouldTraceClassInitialization(clazzName.replace("/", "."))) {
394+
return instrumentClassWithClinit(clazzData);
399395
}
400-
401-
return writer.toByteArray();
396+
return null;
402397
} catch (Throwable e) {
403398
String targetClazzName = clazzName != null ? clazzName : "<unknown class>";
404399
System.err.println("[native-image-diagnostics-agent] Failed to instrument class " + targetClazzName + ": ");
@@ -407,6 +402,48 @@ private byte[] maybeInstrumentClassWithClinit(String clazzName, byte[] clazzData
407402
}
408403
}
409404

405+
/**
406+
* Instruments the given class data with a synthetic <clinit> method if missing. Returns null if
407+
* no changes are made, otherwise the modified classfile bytes.
408+
*/
409+
public byte[] instrumentClassWithClinit(byte[] classData) {
410+
class ClinitAlreadyExistsException extends RuntimeException {
411+
@Serial private static final long serialVersionUID = 1L;
412+
}
413+
try {
414+
ClassModel cm = ClassFile.of().parse(classData);
415+
return ClassFile.of().transformClass(cm, new ClassTransform() {
416+
/**
417+
* Copies over all elements from the original class.
418+
*/
419+
@Override
420+
public void accept(ClassBuilder clb, ClassElement ce) {
421+
if (ce instanceof MethodModel mm && ConstantDescs.CLASS_INIT_NAME.equals((mm.methodName().stringValue()))) {
422+
// already has a <clinit> method
423+
throw new ClinitAlreadyExistsException();
424+
}
425+
clb.with(ce);
426+
}
427+
428+
/**
429+
* Add an empty <clinit> method to the class.
430+
*/
431+
@Override
432+
public void atEnd(ClassBuilder clb) {
433+
clb.withMethodBody(
434+
ConstantDescs.CLASS_INIT_NAME,
435+
ConstantDescs.MTD_void,
436+
ACC_PUBLIC | ClassFile.ACC_STATIC,
437+
cob -> {
438+
cob.return_();
439+
});
440+
}
441+
});
442+
} catch (ClinitAlreadyExistsException e) {
443+
return null;
444+
}
445+
}
446+
410447
@CEntryPoint
411448
@CEntryPointOptions(prologue = AgentIsolate.Prologue.class)
412449
@SuppressWarnings("unused")

0 commit comments

Comments
 (0)