Line data Source code
1 : /* Internals of libgccjit: logging
2 : Copyright (C) 2014-2026 Free Software Foundation, Inc.
3 : Contributed by David Malcolm <dmalcolm@redhat.com>.
4 :
5 : This file is part of GCC.
6 :
7 : GCC is free software; you can redistribute it and/or modify it
8 : under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3, or (at your option)
10 : any later version.
11 :
12 : GCC is distributed in the hope that it will be useful, but
13 : WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with GCC; see the file COPYING3. If not see
19 : <http://www.gnu.org/licenses/>. */
20 :
21 : #ifndef JIT_LOGGING_H
22 : #define JIT_LOGGING_H
23 :
24 : #include "jit-common.h"
25 :
26 : namespace gcc {
27 :
28 : namespace jit {
29 :
30 : /* A gcc::jit::logger encapsulates a logging stream: a way to send
31 : lines of pertinent information to a FILE *. */
32 :
33 : class logger
34 : {
35 : public:
36 : logger (FILE *f_out, int flags, int verbosity);
37 : ~logger ();
38 :
39 : void incref (const char *reason);
40 : void decref (const char *reason);
41 :
42 : void log (const char *fmt, ...)
43 : GNU_PRINTF(2, 3);
44 : void log_va (const char *fmt, va_list ap)
45 : GNU_PRINTF(2, 0);
46 :
47 : void enter_scope (const char *scope_name);
48 : void exit_scope (const char *scope_name);
49 :
50 : private:
51 : int m_refcount;
52 : FILE *m_f_out;
53 : int m_indent_level;
54 : bool m_log_refcount_changes;
55 : };
56 :
57 : /* The class gcc::jit::log_scope is an RAII-style class intended to make
58 : it easy to notify a logger about entering and exiting the body of a
59 : given function. */
60 :
61 : class log_scope
62 : {
63 : public:
64 : log_scope (logger *logger, const char *name);
65 : ~log_scope ();
66 :
67 : private:
68 : logger *m_logger;
69 : const char *m_name;
70 : };
71 :
72 : /* The constructor for gcc::jit::log_scope.
73 :
74 : The normal case is that the logger is NULL, in which case this should
75 : be largely a no-op.
76 :
77 : If we do have a logger, notify it that we're entering the given scope.
78 : We also need to hold a reference on it, to avoid a use-after-free
79 : when logging the cleanup of the owner of the logger. */
80 :
81 : inline
82 203506 : log_scope::log_scope (logger *logger, const char *name) :
83 203506 : m_logger (logger),
84 203506 : m_name (name)
85 : {
86 203506 : if (m_logger)
87 : {
88 133529 : m_logger->incref ("log_scope ctor");
89 133529 : m_logger->enter_scope (m_name);
90 : }
91 203506 : }
92 :
93 : /* The destructor for gcc::jit::log_scope; essentially the opposite of
94 : the constructor. */
95 :
96 : inline
97 203508 : log_scope::~log_scope ()
98 : {
99 203508 : if (m_logger)
100 : {
101 133529 : m_logger->exit_scope (m_name);
102 133529 : m_logger->decref ("log_scope dtor");
103 : }
104 203508 : }
105 :
106 : /* A gcc::jit::log_user is something that potentially uses a
107 : gcc::jit::logger (which could be NULL).
108 :
109 : It is the base class for each of:
110 :
111 : - class gcc::jit::recording::context
112 :
113 : - class gcc::jit::playback::context
114 :
115 : - class gcc::jit::tempdir
116 :
117 : - class gcc::jit::result
118 :
119 : The log_user class keeps the reference-count of a logger up-to-date. */
120 :
121 : class log_user
122 : {
123 : public:
124 : log_user (logger *logger);
125 : ~log_user ();
126 :
127 256807 : logger * get_logger () const { return m_logger; }
128 : void set_logger (logger * logger);
129 :
130 : void log (const char *fmt, ...) const
131 : GNU_PRINTF(2, 3);
132 :
133 : void enter_scope (const char *scope_name);
134 : void exit_scope (const char *scope_name);
135 :
136 : private:
137 : logger *m_logger;
138 : };
139 :
140 : /* A shortcut for calling log from a context/result, handling the common
141 : case where the underlying logger is NULL via a no-op. */
142 :
143 : inline void
144 49082 : log_user::log (const char *fmt, ...) const
145 : {
146 49082 : if (m_logger)
147 : {
148 36868 : va_list ap;
149 36868 : va_start (ap, fmt);
150 36868 : m_logger->log_va (fmt, ap);
151 36868 : va_end (ap);
152 : }
153 49082 : }
154 :
155 : /* A shortcut for recording entry into a scope from a context/result,
156 : handling the common case where the underlying logger is NULL via
157 : a no-op. */
158 :
159 : inline void
160 2662 : log_user::enter_scope (const char *scope_name)
161 : {
162 2662 : if (m_logger)
163 1214 : m_logger->enter_scope (scope_name);
164 : }
165 :
166 : /* A shortcut for recording exit from a scope from a context/result,
167 : handling the common case where the underlying logger is NULL via
168 : a no-op. */
169 :
170 : inline void
171 2662 : log_user::exit_scope (const char *scope_name)
172 : {
173 2662 : if (m_logger)
174 1214 : m_logger->exit_scope (scope_name);
175 : }
176 :
177 : } // namespace gcc::jit
178 :
179 : } // namespace gcc
180 :
181 : /* If the given logger is non-NULL, log entry/exit of this scope to
182 : it, identifying it using __PRETTY_FUNCTION__. */
183 :
184 : #define JIT_LOG_SCOPE(LOGGER) \
185 : gcc::jit::log_scope s (LOGGER, __PRETTY_FUNCTION__)
186 :
187 : /* If the given logger is non-NULL, log entry/exit of this scope to
188 : it, identifying it using __func__. */
189 :
190 : #define JIT_LOG_FUNC(LOGGER) \
191 : gcc::jit::log_scope s (LOGGER, __func__)
192 :
193 : #endif /* JIT_LOGGING_H */
|