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