Skip to content

Commit 6bb56df

Browse files
Add SuspiciousHostAccessCollector
Setting `-Dsuspicious.host.access.collector.enabled=true` will dump a stack tree of all the accesses to some platform-dependent methods of the host graal providers.
1 parent cf7367c commit 6bb56df

File tree

4 files changed

+119
-2
lines changed

4 files changed

+119
-2
lines changed

espresso-compiler-stub/mx.espresso-compiler-stub/suite.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@
7979
"jdk.vm.ci.runtime",
8080
],
8181
},
82-
"javaCompliance": "8+",
82+
"javaCompliance": "21+",
8383
"checkstyle": "com.oracle.truffle.espresso",
8484
},
8585
},

espresso-compiler-stub/src/com.oracle.truffle.espresso.graal/src/com/oracle/truffle/espresso/graal/DummyEspressoGraalJVMCICompiler.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import jdk.vm.ci.runtime.JVMCIRuntime;
3131

3232
public final class DummyEspressoGraalJVMCICompiler implements GraalJVMCICompiler {
33-
3433
private final EspressoGraalRuntime runtime;
3534

3635
private DummyEspressoGraalJVMCICompiler(JVMCIRuntime jvmciRuntime) {

espresso-compiler-stub/src/com.oracle.truffle.espresso.graal/src/com/oracle/truffle/espresso/graal/DummyLoweringProvider.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public ValueNode reconstructArrayIndex(JavaKind elementKind, AddressNode address
5454

5555
@Override
5656
public Integer smallestCompareWidth() {
57+
SuspiciousHostAccessCollector.onSuspiciousHostAccess();
5758
// used at least by AutomaticUnsafeTransformationSupport.getStaticInitializerGraph
5859
return null;
5960
}
@@ -75,12 +76,14 @@ public boolean supportsImplicitNullChecks() {
7576

7677
@Override
7778
public boolean writesStronglyOrdered() {
79+
SuspiciousHostAccessCollector.onSuspiciousHostAccess();
7880
// used at least by AutomaticUnsafeTransformationSupport.getStaticInitializerGraph
7981
return false;
8082
}
8183

8284
@Override
8385
public TargetDescription getTarget() {
86+
SuspiciousHostAccessCollector.onSuspiciousHostAccess();
8487
// used at least by AutomaticUnsafeTransformationSupport.getStaticInitializerGraph
8588
return target;
8689
}
@@ -92,6 +95,7 @@ public BarrierSet getBarrierSet() {
9295

9396
@Override
9497
public boolean divisionOverflowIsJVMSCompliant() {
98+
SuspiciousHostAccessCollector.onSuspiciousHostAccess();
9599
// used at least by AutomaticUnsafeTransformationSupport.getStaticInitializerGraph
96100
return false;
97101
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
* Copyright (c) 2025, 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
package com.oracle.truffle.espresso.graal;
24+
25+
import java.io.PrintStream;
26+
import java.util.HashMap;
27+
import java.util.Map;
28+
29+
/**
30+
* Helps collect stack traces of calls to some methods that probably shouldn't be called. For
31+
* example when using {@link EspressoGraalRuntime} in the context of running native-image on top of
32+
* espresso, we shouldn't expect any calls to methods that query machine-specific details.
33+
* <p>
34+
* Such methods should call {@link #onSuspiciousHostAccess}.
35+
* <p>
36+
* Setting {@code suspicious.host.access.collector.enabled} to {@code true} will enable collection
37+
* of the call-sites of those methods and report the tree of stack traces reaching them on exit.
38+
*/
39+
final class SuspiciousHostAccessCollector {
40+
private static final boolean ENABLED = Boolean.getBoolean("suspicious.host.access.collector.enabled");
41+
private static final Node ROOT = new Node();
42+
static {
43+
if (ENABLED) {
44+
Runtime.getRuntime().addShutdownHook(new Thread() {
45+
@Override
46+
public void run() {
47+
dumpSuspiciousAccesses(System.out);
48+
}
49+
});
50+
}
51+
}
52+
53+
static void onSuspiciousHostAccess() {
54+
if (!ENABLED) {
55+
return;
56+
}
57+
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
58+
add(stackTrace);
59+
}
60+
61+
static void dumpSuspiciousAccesses(PrintStream out) {
62+
out.println("Suspicious host accesses:");
63+
ROOT.dump(out, 0);
64+
}
65+
66+
private static void add(StackTraceElement[] stackTrace) {
67+
Node currentNode = ROOT;
68+
int currentIndex = 2;
69+
while (currentIndex < stackTrace.length) {
70+
StackTraceElement element = stackTrace[currentIndex];
71+
currentNode = currentNode.add(element);
72+
currentIndex++;
73+
}
74+
}
75+
76+
private static final class Node {
77+
Map<StackTraceElement, Node> children;
78+
79+
synchronized Node add(StackTraceElement element) {
80+
if (children == null) {
81+
Node child = new Node();
82+
children = Map.of(element, child);
83+
return child;
84+
}
85+
Node existing = children.get(element);
86+
if (existing != null) {
87+
return existing;
88+
}
89+
Node newChild = new Node();
90+
if (children.size() == 1) {
91+
Map.Entry<StackTraceElement, Node> oldEntry = children.entrySet().iterator().next();
92+
children = HashMap.newHashMap(2);
93+
children.put(oldEntry.getKey(), oldEntry.getValue());
94+
}
95+
children.put(element, newChild);
96+
return newChild;
97+
}
98+
99+
void dump(PrintStream out, int indent) {
100+
if (children == null) {
101+
return;
102+
}
103+
int nextIndent = children.size() > 1 ? indent + 1 : indent;
104+
for (Map.Entry<StackTraceElement, Node> entry : children.entrySet()) {
105+
StringBuilder sb = new StringBuilder();
106+
sb.repeat(" ", indent);
107+
sb.append("* ");
108+
sb.append(entry.getKey());
109+
out.println(sb);
110+
entry.getValue().dump(out, nextIndent);
111+
}
112+
}
113+
}
114+
}

0 commit comments

Comments
 (0)