RFR: 8360389: Support printing from C2 compiled code [v8]
Emanuel Peter
epeter at openjdk.org
Mon Sep 1 13:17:46 UTC 2025
On Tue, 26 Aug 2025 14:41:21 GMT, Benoît Maillard <bmaillard at openjdk.org> wrote:
>> This PR adds support for printf-style debugging from C2 compiled code. This is implemented as a runtime call to a C++ method that prints the values of the nodes passed as arguments. The runtime C++ method is implemented with the help of variadic templates, as it is expected to support various combinations of argument types.
>>
>> ## Usage
>>
>> Suppose we have this piece of Java code, that simply computes an arithmetic operation, and
>> that we compile `square` with C2.
>>
>> class Square {
>> static int square(int a) {
>> return a * a;
>> }
>>
>> public static void main(String[] args) {
>> square(9);
>> }
>> }
>>
>>
>> We would like to inspect the node that contains the value returned in this method.
>> We can add a call to `Compile::make_debug_print` and pass a message, the IGVN instance, as well as the node(s) that we would like to inspect.
>>
>> ```c++
>> void Compile::return_values(JVMState* jvms) {
>> GraphKit kit(jvms);
>> Node* ret = new ReturnNode(TypeFunc::Parms,
>> kit.control(),
>> kit.i_o(),
>> kit.reset_memory(),
>> kit.frameptr(),
>> kit.returnadr());
>> // Add zero or 1 return values
>> int ret_size = tf()->range()->cnt() - TypeFunc::Parms;
>>
>>
>> Node* return_value;
>> if (ret_size > 0) {
>> kit.inc_sp(-ret_size); // pop the return value(s)
>> kit.sync_jvms();
>> return_value = kit.argument(0);
>> ret->add_req(return_value);
>>
>> // <-------------------- Simply insert this
>> C->make_debug_print<jint>("return: ", initial_gvn(), return_value);
>> }
>>
>> // bind it to root
>> root()->add_req(ret);
>> record_for_igvn(ret);
>> initial_gvn()->transform(ret);
>> }
>>
>>
>> We can then call run our code with `-XX:CompileCommand="compileonly,Square::square`
>> and we get the following output:
>>
>>
>> return:
>> int 81
>>
>>
>> This case is of course trivial, but more useful examples are shown later.
>>
>> ## Implementation
>>
>> The debugging capability is implemented as a runtime call to a C++ printing method. For this, `Compile::make_debug_print` inserts a `CallLeafNode` into the graph and rewires control flow as needed.
>>
>> The actual printing is handled by the `SharedRuntime::debug_print` method, written with a variadic template to support various argument type combinations. A pointer to this runtime method is obtained at compile time and is passed to the ...
>
> Benoît Maillard has updated the pull request incrementally with one additional commit since the last revision:
>
> Fix mismatch with #ifdef COMPILER2 between .hpp and .cpp
I have not read the PR in any detail. Just tried to use it in a bug I'm trying to fix. [JDK-8366490](https://bugs.openjdk.org/browse/JDK-8366490)
So I did this:
diff --git a/src/hotspot/share/opto/vectorization.cpp b/src/hotspot/share/opto/vectorization.cpp
index cd5aba6c31d..1b1f7c2f6f2 100644
--- a/src/hotspot/share/opto/vectorization.cpp
+++ b/src/hotspot/share/opto/vectorization.cpp
@@ -1046,6 +1046,8 @@ BoolNode* VPointer::make_speculative_aliasing_check_with(const VPointer& other)
tty->print("size2: "); size2->dump();
tty->print_cr("span1: "); span1->dump_bfs(5, nullptr, "");
tty->print_cr("span2: "); span2->dump_bfs(5, nullptr, "");
+
+ phase->C->make_debug_print<jlong>("span ", &igvn, span1);
}
#endif
And ran my test:
`./java -XX:CompileCommand=quiet -XX:CompileCommand=compileonly,Reduced1::test -XX:CompileCommand=printcompilation,Reduced1::* -XX:CompileCommand=dontinline,Reduced1::allocateArrays -XX:-TieredCompilation -Xbatch -XX:+StressGCM -XX:+TraceLoopOpts -XX:CompileCommand=TraceAutoVectorization,Reduced1::test,SW_INFO,SPECULATIVE_ALIASING_ANALYSIS -XX:+TraceNewVectors -XX:-LoopMultiversioning -XX:SuperWordAutomaticAlignment=0 -XX:+TraceDeoptimization Reduced1.java`
class Reduced1 {
static final int N = 400;
static void allocateArrays() {
for (int i = 0; 200_000 > i; ++i) {
int[] a = new int[N];
}
}
static int[] test() {
int a[] = new int[N];
allocateArrays();
for (int k = 0; k < 500; k++) {
for (int i = 1; i < 69; i++) {
a[i] = 14;
a[4] -= 14;
}
}
return a;
}
public static void main(String[] args) {
int[] gold = test();
for (int r = 0; r < 10; r++) {
int[] a = test();
System.out.println("a[4]: " + a[4]);
if (a[4] != gold[4]) {
throw new RuntimeException("wrong value " + gold[4] + " " + a[4]);
}
}
}
}
But that got me some assert:
# Internal Error (/home/empeter/Documents/oracle/jdk-fork2/open/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp:1126), pid=2630187, tid=2630207
# assert((i + 1) < total_args_passed && sig_bt[i + 1] == T_VOID) failed: expecting half
33 Stack: [0x00007fe32ed13000,0x00007fe32ee13000], sp=0x00007fe32ee0e8d0, free space=1006k
34 Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
35 V [libjvm.so+0x19a3163] SharedRuntime::c_calling_convention(BasicType const*, VMRegPair*, int)+0x673 (sharedRuntime_x86_64.cpp:1126)
36 V [libjvm.so+0x1658abe] Matcher::match_sfpt(SafePointNode*)+0xd6e (matcher.cpp:1396)
37 V [libjvm.so+0x165b695] Matcher::xform(Node*, int)+0x1075 (matcher.cpp:1159)
38 V [libjvm.so+0x1661b53] Matcher::match()+0x1113 (matcher.cpp:369)
39 V [libjvm.so+0xb7b6ce] Compile::Code_Gen()+0x1fe (compile.cpp:3024)
40 V [libjvm.so+0xb81103] Compile::Compile(ciEnv*, ciMethod*, int, Options, DirectiveSet*)+0x1fd3 (compile.cpp:892)
41 V [libjvm.so+0x9a1f76] C2Compiler::compile_method(ciEnv*, ciMethod*, int, bool, DirectiveSet*)+0x466 (c2compiler.cpp:147)
42 V [libjvm.so+0xb904c8] CompileBroker::invoke_compiler_on_method(CompileTask*)+0xb48 (compileBroker.cpp:2342)
43 V [libjvm.so+0xb91650] CompileBroker::compiler_thread_loop()+0x530 (compileBroker.cpp:1986)
44 V [libjvm.so+0x10f258b] JavaThread::thread_main_inner()+0x13b (javaThread.cpp:775)
45 V [libjvm.so+0x1b63d16] Thread::call_run()+0xb6 (thread.cpp:243)
46 V [libjvm.so+0x17d94d8] thread_native_entry(Thread*)+0x128 (os_linux.cpp:892)
Am I doing something wrong here, or is that maybe a limitation of the current implementation?
-------------
PR Comment: https://git.openjdk.org/jdk/pull/26475#issuecomment-3242340816
More information about the hotspot-dev
mailing list