From 14d5b9e8f5480e5fe7430d075f3d140fbd72d9da Mon Sep 17 00:00:00 2001
From: Josef Eisl <josef.eisl@oracle.com>
Date: Fri, 31 Jan 2025 12:34:32 +0100
Subject: [PATCH 1/4] svm: add SVM_JFR module

---
 substratevm/mx.substratevm/suite.py | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/substratevm/mx.substratevm/suite.py b/substratevm/mx.substratevm/suite.py
index 348697aae502..feaa746b0792 100644
--- a/substratevm/mx.substratevm/suite.py
+++ b/substratevm/mx.substratevm/suite.py
@@ -2513,6 +2513,28 @@
             "maven" : False,
         },
 
+        "SVM_JFR": {
+            "subDir": "src",
+            "description" : "SubstrateVM support for the JFR",
+            "dependencies": [
+                "com.oracle.svm.hosted.foreign",
+            ],
+            "distDependencies": [
+                "compiler:GRAAL",
+                "SVM"
+            ],
+            "moduleInfo" : {
+                "name" : "org.graalvm.nativeimage.jfr",
+                "requires" : [
+                    "org.graalvm.nativeimage.builder"
+                ],
+                "exports" : [
+                    "* to org.graalvm.nativeimage.builder"
+                ],
+            },
+            "maven" : False,
+        },
+
         "SVM_LLVM" : {
             "subDir" : "src",
             "description" : "LLVM backend for Native Image",

From 0c613b38146270c7424ad430cfa1193d349b95d1 Mon Sep 17 00:00:00 2001
From: Josef Eisl <josef.eisl@oracle.com>
Date: Fri, 31 Jan 2025 16:40:00 +0100
Subject: [PATCH 2/4] svm: add jfr project

---
 substratevm/mx.substratevm/mx_substratevm.py  |  1 +
 substratevm/mx.substratevm/suite.py           | 23 +++++++++++++++----
 .../com/oracle/svm/core/jfr/package-info.java |  1 +
 3 files changed, 21 insertions(+), 4 deletions(-)
 create mode 100644 substratevm/src/com.oracle.svm.core.jfr/src/com/oracle/svm/core/jfr/package-info.java

diff --git a/substratevm/mx.substratevm/mx_substratevm.py b/substratevm/mx.substratevm/mx_substratevm.py
index 087ba1336595..ca2a67ef9449 100644
--- a/substratevm/mx.substratevm/mx_substratevm.py
+++ b/substratevm/mx.substratevm/mx_substratevm.py
@@ -1231,6 +1231,7 @@ def native_image_context_run(func, func_args=None, config=None, build_if_missing
         'substratevm:OBJECTFILE',
         'substratevm:POINTSTO',
         'substratevm:NATIVE_IMAGE_BASE',
+        'substratevm:SVM_JFR',
     ] + (['substratevm:SVM_FOREIGN'] if mx_sdk_vm.base_jdk().javaCompliance >= '22' else []),
     support_distributions=['substratevm:SVM_GRAALVM_SUPPORT'],
     extra_native_targets=['linux-default-glibc', 'linux-default-musl'] if mx.is_linux() and not mx.get_arch() == 'riscv64' else None,
diff --git a/substratevm/mx.substratevm/suite.py b/substratevm/mx.substratevm/suite.py
index feaa746b0792..e24e99167497 100644
--- a/substratevm/mx.substratevm/suite.py
+++ b/substratevm/mx.substratevm/suite.py
@@ -787,6 +787,21 @@
             "spotbugs" : "false",
         },
 
+        "com.oracle.svm.core.jfr": {
+            "subDir": "src",
+            "sourceDirs": ["src"],
+            "dependencies": [
+                "com.oracle.svm.core"
+            ],
+            "javaCompliance" : "21+",
+            "annotationProcessors": [
+                "compiler:GRAAL_PROCESSOR",
+                "SVM_PROCESSOR",
+            ],
+            "checkstyle": "com.oracle.svm.hosted",
+            "workingSets": "SVM",
+        },
+
         "com.oracle.svm.hosted.foreign": {
             "subDir": "src",
             "sourceDirs": ["src"],
@@ -2517,7 +2532,7 @@
             "subDir": "src",
             "description" : "SubstrateVM support for the JFR",
             "dependencies": [
-                "com.oracle.svm.hosted.foreign",
+                "com.oracle.svm.core.jfr",
             ],
             "distDependencies": [
                 "compiler:GRAAL",
@@ -2528,9 +2543,9 @@
                 "requires" : [
                     "org.graalvm.nativeimage.builder"
                 ],
-                "exports" : [
-                    "* to org.graalvm.nativeimage.builder"
-                ],
+                # "exports" : [
+                #     "* to org.graalvm.nativeimage.builder"
+                # ],
             },
             "maven" : False,
         },
diff --git a/substratevm/src/com.oracle.svm.core.jfr/src/com/oracle/svm/core/jfr/package-info.java b/substratevm/src/com.oracle.svm.core.jfr/src/com/oracle/svm/core/jfr/package-info.java
new file mode 100644
index 000000000000..fd87f9e8b715
--- /dev/null
+++ b/substratevm/src/com.oracle.svm.core.jfr/src/com/oracle/svm/core/jfr/package-info.java
@@ -0,0 +1 @@
+package com.oracle.svm.core.jfr;
\ No newline at end of file

From 372cdafc5b1b02ec855eee6945373ee0f4b1fdfe Mon Sep 17 00:00:00 2001
From: Josef Eisl <josef.eisl@oracle.com>
Date: Mon, 3 Feb 2025 10:35:54 +0100
Subject: [PATCH 3/4] svm: make jfr a macro

---
 substratevm/mx.substratevm/mx_substratevm.py | 15 ++++++++++++++-
 substratevm/mx.substratevm/suite.py          |  8 ++++++++
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/substratevm/mx.substratevm/mx_substratevm.py b/substratevm/mx.substratevm/mx_substratevm.py
index ca2a67ef9449..a2c087379599 100644
--- a/substratevm/mx.substratevm/mx_substratevm.py
+++ b/substratevm/mx.substratevm/mx_substratevm.py
@@ -1231,7 +1231,6 @@ def native_image_context_run(func, func_args=None, config=None, build_if_missing
         'substratevm:OBJECTFILE',
         'substratevm:POINTSTO',
         'substratevm:NATIVE_IMAGE_BASE',
-        'substratevm:SVM_JFR',
     ] + (['substratevm:SVM_FOREIGN'] if mx_sdk_vm.base_jdk().javaCompliance >= '22' else []),
     support_distributions=['substratevm:SVM_GRAALVM_SUPPORT'],
     extra_native_targets=['linux-default-glibc', 'linux-default-musl'] if mx.is_linux() and not mx.get_arch() == 'riscv64' else None,
@@ -1669,6 +1668,20 @@ def prevent_build_path_in_libgraal():
 
 mx_sdk_vm.register_graalvm_component(libsvmjdwp)
 
+mx_sdk_vm.register_graalvm_component(mx_sdk_vm.GraalVMSvmMacro(
+    suite=suite,
+    name='SubstrateVM JFR Support',
+    short_name='svmjfr',
+    dir_name="svmjfr",
+    license_files=[],
+    third_party_license_files=[],
+    dependencies=['SubstrateVM'],
+    builder_jar_distributions=['substratevm:SVM_JFR'],
+    support_distributions=['substratevm:SVM_JFR_SUPPORT'],
+    stability="experimental",
+    jlink=False,
+))
+
 def _native_image_configure_extra_jvm_args():
     packages = ['jdk.graal.compiler/jdk.graal.compiler.phases.common', 'jdk.internal.vm.ci/jdk.vm.ci.meta', 'jdk.internal.vm.ci/jdk.vm.ci.services', 'jdk.graal.compiler/jdk.graal.compiler.core.common.util']
     args = ['--add-exports=' + packageName + '=ALL-UNNAMED' for packageName in packages]
diff --git a/substratevm/mx.substratevm/suite.py b/substratevm/mx.substratevm/suite.py
index e24e99167497..2a26269a289a 100644
--- a/substratevm/mx.substratevm/suite.py
+++ b/substratevm/mx.substratevm/suite.py
@@ -2550,6 +2550,14 @@
             "maven" : False,
         },
 
+        "SVM_JFR_SUPPORT" : {
+            "native" : True,
+            "description" : "JFR support",
+            "layout" : {
+                "native-image.properties" : "file:mx.substratevm/macro-svmjfr.properties",
+            },
+        },
+
         "SVM_LLVM" : {
             "subDir" : "src",
             "description" : "LLVM backend for Native Image",

From 7ae063f6d58bad37286f8f1cf7937ad1b8b3be40 Mon Sep 17 00:00:00 2001
From: Josef Eisl <josef.eisl@oracle.com>
Date: Fri, 31 Jan 2025 12:34:50 +0100
Subject: [PATCH 4/4] svm: load SVM_JFR module conditionally in the driver

---
 .../mx.substratevm/macro-svmjfr.properties    |  2 ++
 .../oracle/svm/core/VMInspectionOptions.java  |  6 ++++-
 .../svm/driver/CmdLineOptionHandler.java      | 23 +++++++++++++++++++
 3 files changed, 30 insertions(+), 1 deletion(-)
 create mode 100644 substratevm/mx.substratevm/macro-svmjfr.properties

diff --git a/substratevm/mx.substratevm/macro-svmjfr.properties b/substratevm/mx.substratevm/macro-svmjfr.properties
new file mode 100644
index 000000000000..b811a353413d
--- /dev/null
+++ b/substratevm/mx.substratevm/macro-svmjfr.properties
@@ -0,0 +1,2 @@
+# This file contains support for building images with JFR support
+ImageBuilderModulePath = ${.}/builder/svm-jfr.jar
\ No newline at end of file
diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/VMInspectionOptions.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/VMInspectionOptions.java
index 114c811bafa1..9847de50eed1 100644
--- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/VMInspectionOptions.java
+++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/VMInspectionOptions.java
@@ -50,7 +50,7 @@
 import jdk.graal.compiler.options.OptionType;
 
 public final class VMInspectionOptions {
-    private static final String ENABLE_MONITORING_OPTION = "enable-monitoring";
+    public static final String ENABLE_MONITORING_OPTION = "enable-monitoring";
     private static final String MONITORING_DEFAULT_NAME = "<deprecated-default>";
     private static final String MONITORING_ALL_NAME = "all";
     private static final String MONITORING_HEAPDUMP_NAME = "heapdump";
@@ -146,6 +146,10 @@ private static Set<String> getEnabledMonitoringFeatures() {
 
     private static boolean hasAllOrKeywordMonitoringSupport(String keyword) {
         Set<String> enabledFeatures = getEnabledMonitoringFeatures();
+        return includesAllOrKeywordMonitoringSupport(enabledFeatures, keyword);
+    }
+
+    public static boolean includesAllOrKeywordMonitoringSupport(Set<String> enabledFeatures, String keyword) {
         return enabledFeatures.contains(MONITORING_ALL_NAME) || enabledFeatures.contains(MONITORING_DEFAULT_NAME) || enabledFeatures.contains(keyword);
     }
 
diff --git a/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/CmdLineOptionHandler.java b/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/CmdLineOptionHandler.java
index 0110eb07df67..6132d1edb677 100644
--- a/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/CmdLineOptionHandler.java
+++ b/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/CmdLineOptionHandler.java
@@ -25,14 +25,21 @@
 package com.oracle.svm.driver;
 
 import java.io.File;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.List;
 import java.util.Optional;
+import java.util.Set;
 import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
 
 import com.oracle.svm.core.SubstrateOptions;
+import com.oracle.svm.core.SubstrateUtil;
 import com.oracle.svm.core.VM;
+import com.oracle.svm.core.VMInspectionOptions;
 import com.oracle.svm.core.option.OptionOrigin;
 import com.oracle.svm.core.util.ExitStatus;
 import com.oracle.svm.driver.NativeImage.ArgumentQueue;
@@ -54,6 +61,7 @@ class CmdLineOptionHandler extends NativeImage.OptionHandler<NativeImage> {
     /* Defunct legacy options that we have to accept to maintain backward compatibility */
     private static final String VERBOSE_SERVER_OPTION = "--verbose-server";
     private static final String SERVER_OPTION_PREFIX = "--server-";
+    private static final String ENABLE_MONITORING_OPTION = "--" + VMInspectionOptions.ENABLE_MONITORING_OPTION;
 
     private static final String LAUNCHER_NAME = "native-image";
 
@@ -190,6 +198,21 @@ private boolean consume(ArgumentQueue args, String headArg) {
             return true;
         }
 
+        if (headArg.startsWith(ENABLE_MONITORING_OPTION)) {
+            String argValue;
+            if (headArg.length() == ENABLE_MONITORING_OPTION.length()) {
+                assert ENABLE_MONITORING_OPTION.equals(headArg);
+                argValue = "all";
+            } else {
+                argValue = args.peek().substring(ENABLE_MONITORING_OPTION.length() + 1);
+            }
+            Set<String> monitoringArg = Set.of(argValue.split(","));
+            if (VMInspectionOptions.includesAllOrKeywordMonitoringSupport(monitoringArg, "jfr")) {
+                args.add("--macro:svmjfr");
+            }
+            return false;
+        }
+
         return false;
     }