jit-logging.h revision 1.1.1.2
1/* Internals of libgccjit: logging 2 Copyright (C) 2014-2016 Free Software Foundation, Inc. 3 Contributed by David Malcolm <dmalcolm@redhat.com>. 4 5This file is part of GCC. 6 7GCC is free software; you can redistribute it and/or modify it 8under the terms of the GNU General Public License as published by 9the Free Software Foundation; either version 3, or (at your option) 10any later version. 11 12GCC is distributed in the hope that it will be useful, but 13WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15General Public License for more details. 16 17You should have received a copy of the GNU General Public License 18along 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 26namespace gcc { 27 28namespace jit { 29 30/* A gcc::jit::logger encapsulates a logging stream: a way to send 31 lines of pertinent information to a FILE *. */ 32 33class 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 50private: 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 61class log_scope 62{ 63public: 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 81inline 82log_scope::log_scope (logger *logger, const char *name) : 83 m_logger (logger), 84 m_name (name) 85{ 86 if (m_logger) 87 { 88 m_logger->incref ("log_scope ctor"); 89 m_logger->enter_scope (m_name); 90 } 91} 92 93/* The destructor for gcc::jit::log_scope; essentially the opposite of 94 the constructor. */ 95 96inline 97log_scope::~log_scope () 98{ 99 if (m_logger) 100 { 101 m_logger->exit_scope (m_name); 102 m_logger->decref ("log_scope dtor"); 103 } 104} 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 121class log_user 122{ 123 public: 124 log_user (logger *logger); 125 ~log_user (); 126 127 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 143inline void 144log_user::log (const char *fmt, ...) const 145{ 146 if (m_logger) 147 { 148 va_list ap; 149 va_start (ap, fmt); 150 m_logger->log_va (fmt, ap); 151 va_end (ap); 152 } 153} 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 159inline void 160log_user::enter_scope (const char *scope_name) 161{ 162 if (m_logger) 163 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 170inline void 171log_user::exit_scope (const char *scope_name) 172{ 173 if (m_logger) 174 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 */ 194