Home | History | Annotate | Line # | Download | only in jit
jit-logging.h revision 1.1.1.4
      1 /* Internals of libgccjit: logging
      2    Copyright (C) 2014-2018 Free Software Foundation, Inc.
      3    Contributed by David Malcolm <dmalcolm (at) 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 log_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 
     96 inline
     97 log_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 
    121 class 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 
    143 inline void
    144 log_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 
    159 inline void
    160 log_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 
    170 inline void
    171 log_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