RFR: 8360389: Support printing from C2 compiled code [v3]
Vladimir Kozlov
kvn at openjdk.org
Tue Aug 19 15:48:39 UTC 2025
On Tue, 19 Aug 2025 07:06:55 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
>> ## 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 a...
>
> Benoît Maillard has updated the pull request incrementally with one additional commit since the last revision:
>
> Use print_cr instead of \n
src/hotspot/share/opto/compile.cpp line 5411:
> 5409: }
> 5410:
> 5411: Node* Compile::make_debug_print_call(const char* str, address call_addr, PhaseGVN* gvn,
I think it should be in graphKit.cpp similar to `GraphKit::make_runtime_call()`
src/hotspot/share/runtime/sharedRuntime.hpp line 642:
> 640: static void print_ic_miss_histogram();
> 641:
> 642: // Runtime methods for printf-style debug nodes
All these methods should be under #ifdef COMPILER2` since they used only by C2.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/26475#discussion_r2285667276
PR Review Comment: https://git.openjdk.org/jdk/pull/26475#discussion_r2285670974
More information about the hotspot-dev
mailing list