From 007d87f08db2c7910d13c8ac7b589f8a04437a9a Mon Sep 17 00:00:00 2001 From: David Kozak Date: Fri, 24 Oct 2025 15:38:28 +0200 Subject: [PATCH] make sure StrengthenGraphsCounters are properly handled by the benchmarking infrastructure --- sdk/mx.sdk/mx_sdk_benchmark.py | 25 +++++++++++++++++-- .../pointsto/results/StrengthenGraphs.java | 6 ++--- .../oracle/svm/util/ImageBuildStatistics.java | 25 ++++++++++++++++--- 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/sdk/mx.sdk/mx_sdk_benchmark.py b/sdk/mx.sdk/mx_sdk_benchmark.py index 745a4802ad09..de72a72e4860 100644 --- a/sdk/mx.sdk/mx_sdk_benchmark.py +++ b/sdk/mx.sdk/mx_sdk_benchmark.py @@ -1348,7 +1348,11 @@ def _get_image_build_stats_rules(self, template: dict, keys: Sequence[str]) -> S return [mx_benchmark.JsonFixedFileRule(f, template, keys) for f in stats_files] def image_build_statistics_rules(self, benchmarks): - objects_list = ["total_array_store", + """ + This method generates rules to collect metrics produced by ImageBuildStatistics. + """ + # Corresponds to BytecodeExceptionKinds. + exception_kinds = ["total_array_store", "total_assertion_error_nullary", "total_assertion_error_object", "total_class_cast", @@ -1360,10 +1364,27 @@ def image_build_statistics_rules(self, benchmarks): "total_null_pointer", "total_out_of_bounds"] metric_objects = ["total_devirtualized_invokes"] - for obj in objects_list: + for obj in exception_kinds: metric_objects.append(obj + "_after_parse_canonicalization") metric_objects.append(obj + "_before_high_tier") metric_objects.append(obj + "_after_high_tier") + + # Example for the bench server: 'invoke-static-after-strengthen-graphs' + strengthen_graphs_counters = [ + "method", + "block", + "is_null", + "instance_of", + "prim_cmp", + "invoke_static", + "invoke_direct", + "invoke_indirect", + "load_field", + "constant", + ] + for counter in strengthen_graphs_counters: + metric_objects.append("total_" + counter + "_before_strengthen_graphs") + metric_objects.append("total_" + counter + "_after_strengthen_graphs") rules = [] for i in range(0, len(metric_objects)): rules += self._get_image_build_stats_rules({ diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/results/StrengthenGraphs.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/results/StrengthenGraphs.java index 51821edeedae..60a06dfb5146 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/results/StrengthenGraphs.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/results/StrengthenGraphs.java @@ -181,8 +181,8 @@ private static void reportNeverNullInstanceFields(BigBang bb) { } } ImageBuildStatistics imageBuildStats = ImageBuildStatistics.counters(); - imageBuildStats.insert("instancefield_neverNull").addAndGet(neverNull); - imageBuildStats.insert("instancefield_canBeNull").addAndGet(canBeNull); + imageBuildStats.createCounter("instancefield_neverNull").addAndGet(neverNull); + imageBuildStats.createCounter("instancefield_canBeNull").addAndGet(canBeNull); } @SuppressWarnings("try") @@ -392,7 +392,7 @@ enum Counter { ImageBuildStatistics imageBuildStats = ImageBuildStatistics.counters(); for (Counter counter : Counter.values()) { - values[counter.ordinal()] = imageBuildStats.insert(location + "_" + counter.name()); + values[counter.ordinal()] = imageBuildStats.createCounter(counter.name(), location); } } diff --git a/substratevm/src/com.oracle.svm.util/src/com/oracle/svm/util/ImageBuildStatistics.java b/substratevm/src/com.oracle.svm.util/src/com/oracle/svm/util/ImageBuildStatistics.java index 88e3f9b35980..d757dccd8c14 100644 --- a/substratevm/src/com.oracle.svm.util/src/com/oracle/svm/util/ImageBuildStatistics.java +++ b/substratevm/src/com.oracle.svm.util/src/com/oracle/svm/util/ImageBuildStatistics.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,12 +31,16 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.function.Consumer; +import org.graalvm.nativeimage.ImageSingletons; + import jdk.graal.compiler.debug.GraalError; import jdk.graal.compiler.nodes.extended.BytecodeExceptionNode; import jdk.graal.compiler.options.Option; import jdk.graal.compiler.options.OptionKey; -import org.graalvm.nativeimage.ImageSingletons; +/** + * This class collects detailed counters that are then saved into the image build statistics file. + */ public class ImageBuildStatistics { public static class Options { @@ -44,6 +48,9 @@ public static class Options { public static final OptionKey CollectImageBuildStatistics = new OptionKey<>(false); } + /** + * Phases in the compilation pipeline where the counters may be collected. + */ public enum CheckCountLocation { BEFORE_STRENGTHEN_GRAPHS, AFTER_STRENGTHEN_GRAPHS, @@ -54,7 +61,12 @@ public enum CheckCountLocation { final TreeMap counters; - public AtomicLong insert(String key) { + /** + * Create a new counter based on the given unique {@code key}. Each counter is represented as an + * {@link AtomicLong} so that it can be updated from multiple compilations happening in + * parallel. + */ + public AtomicLong createCounter(String key) { AtomicLong result = new AtomicLong(); var existing = counters.put(key, result); if (existing != null) { @@ -63,6 +75,13 @@ public AtomicLong insert(String key) { return result; } + /** + * @see #createCounter(String) + */ + public AtomicLong createCounter(String key, CheckCountLocation location) { + return createCounter(getName(key, location)); + } + public void incDevirtualizedInvokeCounter() { counters.get(devirtualizedInvokes()).incrementAndGet(); }