Skip to content

8360389: Support printing from C2 compiled code #26475

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 22 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
582f603
8360389: add runtime function definitions
benoitmaillard Jul 7, 2025
de3a33c
8360389: Add make_debug_print helper
benoitmaillard Jul 7, 2025
98e9964
8360389: Use flag instead of 0
benoitmaillard Jul 7, 2025
0afb57f
8360389: Add argument debug_print method
benoitmaillard Jul 7, 2025
1ab4032
8360389: Add constant pointer node
benoitmaillard Jul 7, 2025
459e5b7
8360389: Add int argument to print
benoitmaillard Jul 8, 2025
69c26c4
8360389: Add debug_print template
benoitmaillard Jul 25, 2025
28ce64b
Fix types for signatures
benoitmaillard Jul 15, 2025
519e45a
8360389: Add missing primitive types
benoitmaillard Jul 18, 2025
d1ead1d
8360389: Add support for oop
benoitmaillard Jul 21, 2025
7893e87
8360389: Replace templates with checks on c2 types for building signa…
benoitmaillard Jul 23, 2025
045cf95
8360389: Use oopDesc* instead of oop to avoid unexpected behavior lin…
benoitmaillard Jul 23, 2025
4a80e4d
8360389: Remove import
benoitmaillard Jul 23, 2025
502f036
8360389: Add default case
benoitmaillard Jul 23, 2025
0054c59
8360389: Remove useless code
benoitmaillard Jul 25, 2025
d5ce58e
8360389: Refactor
benoitmaillard Jul 25, 2025
37495fa
8360389: More refactoring
benoitmaillard Jul 25, 2025
04ea5f7
8360389: Formatting
benoitmaillard Jul 25, 2025
0029478
8360389: Fix bad refactor
benoitmaillard Jul 25, 2025
af54831
8360389: Missing stuff
benoitmaillard Jul 25, 2025
a879709
8360389: Add missing transform
benoitmaillard Jul 28, 2025
ac10cb0
8360389: Use Type::get_const_basic_type
benoitmaillard Jul 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/hotspot/share/opto/graphKit.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#ifndef SHARE_OPTO_GRAPHKIT_HPP
#define SHARE_OPTO_GRAPHKIT_HPP

#include "runtime.hpp"
#include "ci/ciEnv.hpp"
#include "ci/ciMethodData.hpp"
#include "gc/shared/c2/barrierSetC2.hpp"
Expand Down Expand Up @@ -773,6 +774,20 @@ class GraphKit : public Phase {
Node* parm4 = nullptr, Node* parm5 = nullptr,
Node* parm6 = nullptr, Node* parm7 = nullptr);

#ifndef PRODUCT
// Creates a CallLeafNode that prints a static string and the values of the nodes passed as arguments
template <typename... TT, typename... NN>
Node* make_debug_print(const char* str, NN... in) {
int flags = RC_LEAF;
address call_addr = CAST_FROM_FN_PTR(address, SharedRuntime::debug_print<TT...>);

Node* str_node = new ConPNode(TypeRawPtr::make(((address) str)));
Node* call = make_runtime_call(flags, OptoRuntime::debug_print_Type(in...), call_addr, "debug_print", TypeRawPtr::BOTTOM, str_node, in...);

return call;
}
#endif // PRODUCT

Node* sign_extend_byte(Node* in);
Node* sign_extend_short(Node* in);

Expand Down
79 changes: 79 additions & 0 deletions src/hotspot/share/opto/runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1780,6 +1780,85 @@ static const TypeFunc* make_osr_end_Type() {
return TypeFunc::make(domain, range);
}

#ifndef PRODUCT
void OptoRuntime::debug_print_convert_type(const Type** fields, int* argp, Node *parm) {
switch (parm->bottom_type()->basic_type()) {
case T_BOOLEAN:
fields[(*argp)++] = TypeInt::BOOL;
break;
case T_CHAR:
fields[(*argp)++] = TypeInt::CHAR;
break;
case T_FLOAT:
fields[(*argp)++] = Type::FLOAT;
break;
case T_DOUBLE:
fields[(*argp)++] = Type::DOUBLE;
fields[(*argp)++] = Type::HALF;
break;
case T_BYTE:
fields[(*argp)++] = TypeInt::BYTE;
break;
case T_SHORT:
fields[(*argp)++] = TypeInt::SHORT;
break;
case T_INT:
fields[(*argp)++] = TypeInt::INT;
break;
case T_LONG:
fields[(*argp)++] = TypeLong::LONG;
fields[(*argp)++] = Type::HALF;
break;
case T_OBJECT:
fields[(*argp)++] = TypePtr::NOTNULL;
break;
case T_VOID: // half of long/double
break;
default:
ShouldNotReachHere();
break;
}
}

const TypeFunc* OptoRuntime::debug_print_Type(Node* parm0, Node* parm1,
Node* parm2, Node* parm3,
Node* parm4, Node* parm5,
Node* parm6) {
int argcnt = 1;
if (parm0 != nullptr) { argcnt++;
if (parm1 != nullptr) { argcnt++;
if (parm2 != nullptr) { argcnt++;
if (parm3 != nullptr) { argcnt++;
if (parm4 != nullptr) { argcnt++;
if (parm5 != nullptr) { argcnt++;
if (parm6 != nullptr) { argcnt++;
/* close each nested if ===> */ } } } } } } }

// create input type (domain)
const Type** fields = TypeTuple::fields(argcnt);
int argp = TypeFunc::Parms;
fields[argp++] = TypePtr::NOTNULL; // static string pointer

if (parm0 != nullptr) { debug_print_convert_type(fields, &argp, parm0);
if (parm1 != nullptr) { debug_print_convert_type(fields, &argp, parm1);
if (parm2 != nullptr) { debug_print_convert_type(fields, &argp, parm2);
if (parm3 != nullptr) { debug_print_convert_type(fields, &argp, parm3);
if (parm4 != nullptr) { debug_print_convert_type(fields, &argp, parm4);
if (parm5 != nullptr) { debug_print_convert_type(fields, &argp, parm5);
if (parm6 != nullptr) { debug_print_convert_type(fields, &argp, parm6);
/* close each nested if ===> */ } } } } } } }

assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);

// no result type needed
fields = TypeTuple::fields(1);
fields[TypeFunc::Parms+0] = nullptr; // void
const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
return TypeFunc::make(domain, range);
}
#endif // PRODUCT

//-------------------------------------------------------------------------------------
// register policy

Expand Down
14 changes: 14 additions & 0 deletions src/hotspot/share/opto/runtime.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,20 @@ class OptoRuntime : public AllStatic {
return _dtrace_object_alloc_Type;
}

#ifndef PRODUCT
private:
static void debug_print_convert_type(const Type** fields, int* argp, Node *parm);

public:
// Signature for runtime calls in debug printing nodes, which depends on which nodes are actually passed
// Note: we do not allow more than 7 node arguments as GraphKit::make_runtime_call only allows 8, and we need
// one for the static string
static const TypeFunc* debug_print_Type(Node* parm0 = nullptr, Node* parm1 = nullptr,
Node* parm2 = nullptr, Node* parm3 = nullptr,
Node* parm4 = nullptr, Node* parm5 = nullptr,
Node* parm6 = nullptr);
#endif // PRODUCT

private:
static NamedCounter * volatile _named_counters;

Expand Down
34 changes: 34 additions & 0 deletions src/hotspot/share/runtime/sharedRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,40 @@ void SharedRuntime::print_ic_miss_histogram() {
tty->print_cr("Total IC misses: %7d", tot_misses);
}
}

// Runtime methods for printf-style debug nodes
void SharedRuntime::debug_print_value(jfloat x) {
tty->print("[%f] ", x);
}

void SharedRuntime::debug_print_value(jdouble x) {
tty->print("[%lf] ", x);
}

void SharedRuntime::debug_print_value(jchar x) {
tty->print("[%c] ", x);
}

void SharedRuntime::debug_print_value(jshort x) {
tty->print("[%d] ", x);
}

void SharedRuntime::debug_print_value(jboolean x) {
tty->print("[%d] ", x);
}

void SharedRuntime::debug_print_value(jint x) {
tty->print("[%d] ", x);
}

void SharedRuntime::debug_print_value(jlong x) {
tty->print("[%ld] ", x);
}

void SharedRuntime::debug_print_value(oopDesc* x) {
x->print();
}

#endif // PRODUCT


Expand Down
32 changes: 32 additions & 0 deletions src/hotspot/share/runtime/sharedRuntime.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#ifndef SHARE_RUNTIME_SHAREDRUNTIME_HPP
#define SHARE_RUNTIME_SHAREDRUNTIME_HPP

#include "safepointVerifiers.hpp"
#include "classfile/compactHashtable.hpp"
#include "code/codeBlob.hpp"
#include "code/vmreg.hpp"
Expand Down Expand Up @@ -638,6 +639,37 @@ class SharedRuntime: AllStatic {
static void print_call_statistics(uint64_t comp_total);
static void print_ic_miss_histogram();

// Runtime methods for printf-style debug nodes
static void debug_print_value(jfloat x);
static void debug_print_value(jdouble x);
static void debug_print_value(jchar x);
static void debug_print_value(jshort x);
static void debug_print_value(jboolean x);
static void debug_print_value(jint x);
static void debug_print_value(jlong x);
static void debug_print_value(oopDesc* x);

template <typename T, typename... Rest>
static void debug_print_rec(T arg, Rest... args) {
debug_print_value(arg);
debug_print_rec(args...);
}

static void debug_print_rec() {}

// template is required here as we need to know the exact signature at compile-time
template <typename... TT>
static void debug_print(const char *format, TT... args) {
// these three lines are the manual expansion of JRT_LEAF ... JRT_END, does not work well with templates
DEBUG_ONLY(NoHandleMark __hm;)
os::verify_stack_alignment();
DEBUG_ONLY(NoSafepointVerifier __nsv;)

tty->print("%s", format);
debug_print_rec(args...);
tty->print_cr("");
}

#endif // PRODUCT

static void print_statistics() PRODUCT_RETURN;
Expand Down