tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Logging.h (5152B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      3 * This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 // An experimental logging interface for connecting the JS Engine to some
      8 // (*cough*Gecko*cough*) consumer.
      9 
     10 #ifndef _js_vm_Logging_h_
     11 #define _js_vm_Logging_h_
     12 
     13 #include "mozilla/Assertions.h"
     14 #include "mozilla/LoggingCore.h"
     15 
     16 #include "jit/JitSpewer.h"
     17 #include "js/experimental/LoggingInterface.h"
     18 
     19 struct JSContext;
     20 
     21 namespace js {
     22 
     23 using mozilla::LogLevel;
     24 
     25 // [SMDOC] js::LogModule
     26 //
     27 // js::LogModule is the underlying type used for JS_LOG.
     28 //
     29 // To support declaring these statically, while simultaneously supporting the
     30 // initialization of the interfaces via a callback, each instance of LogModule
     31 // is registered in a module register (logModuleRegistry), which updates
     32 // the module interface for each log module.
     33 //
     34 // Log modules are declared below using a Macro to support the metaprogramming
     35 // required around their storage an initialization.
     36 class LogModule {
     37 public:
     38  explicit constexpr LogModule(const char* name) : name(name) {
     39    MOZ_ASSERT(name);
     40  }
     41 
     42  // Return true iff we should log a message at this level.
     43  inline bool shouldLog(mozilla::LogLevel level) const {
     44    if (!isSetup()) {
     45      return false;
     46    }
     47 
     48    return *levelPtr >= level;
     49  }
     50 
     51  // Initialize all LogModules to speak with the provided interface.
     52  [[nodiscard]] static bool initializeAll(const JS::LoggingInterface iface);
     53 
     54 public:
     55  // Public as it's used by the macro below, and we don't need a
     56  // forwarding interface.
     57  mutable JS::LoggingInterface interface{};
     58 
     59  // Opaque logger obtained via the interface; also public for macro useage.
     60  mutable JS::OpaqueLogger logger{};
     61 
     62  // Name of this logger
     63  const char* name{};
     64 
     65 private:
     66  // Is this logger ready to be used.
     67  inline bool isSetup() const { return interface.isComplete() && logger; }
     68 
     69  // Initialize this Log module
     70  bool initialize(const JS::LoggingInterface iface) const {
     71    // Grab a local copy of the iface.
     72    interface = iface;
     73    MOZ_ASSERT(iface.isComplete());
     74    logger = iface.getLoggerByName(name);
     75    if (!logger) {
     76      return false;
     77    }
     78 
     79    levelPtr = &iface.getLevelRef(logger);
     80    return true;
     81  }
     82 
     83  // Used to fast-path check if we should log.
     84  mutable mozilla::AtomicLogLevel* levelPtr{};
     85 };
     86 
     87 #define FOR_EACH_JS_LOG_MODULE(_)                                            \
     88  _(debug)                /* A predefined log module for casual debugging */ \
     89  _(wasmPerf)             /* Wasm performance statistics */                  \
     90  _(wasmApi)              /* Wasm JS-API tracing */                          \
     91  _(fuseInvalidation)     /* Invalidation triggered by a fuse  */            \
     92  _(thenable)             /* Thenable on standard proto*/                    \
     93  _(startup)              /* engine startup logging */                       \
     94  _(teleporting)          /* Shape Teleporting */                            \
     95  _(selfHosted)           /* self-hosted script logging */                   \
     96  _(gc)                   /* The garbage collector */                        \
     97  _(mtq)                  /* MicroTask queue */                              \
     98  JITSPEW_CHANNEL_LIST(_) /* A module for each JitSpew channel. */
     99 
    100 // Declare Log modules
    101 #define DECLARE_MODULE(X) inline constexpr LogModule X##Module(#X);
    102 
    103 FOR_EACH_JS_LOG_MODULE(DECLARE_MODULE);
    104 
    105 #undef DECLARE_MODULE
    106 
    107 // By default JS_LOGGING is enabled; but if we would like this become
    108 // conditional this file-internal macro can be used to accomplish that.
    109 #define JS_LOGGING 1
    110 
    111 // The core logging macro for the JS Engine.
    112 #ifdef JS_LOGGING
    113 #  define JS_SHOULD_LOG(name, log_level) \
    114    name##Module.shouldLog(LogLevel::log_level)
    115 
    116 #  define JS_LOG(name, log_level, ...)                                     \
    117    do {                                                                   \
    118      if (name##Module.shouldLog(LogLevel::log_level)) {                   \
    119        name##Module.interface.logPrint(name##Module.logger,               \
    120                                        LogLevel::log_level, __VA_ARGS__); \
    121      }                                                                    \
    122    } while (0);
    123 #  define JS_LOG_FMT(name, log_level, fmt, ...)                             \
    124    do {                                                                    \
    125      if (name##Module.shouldLog(LogLevel::log_level)) {                    \
    126        name##Module.interface.logPrintFmt(name##Module.logger,             \
    127                                           LogLevel::log_level,             \
    128                                           FMT_STRING(fmt), ##__VA_ARGS__); \
    129      }                                                                     \
    130    } while (0);
    131 #else
    132 #  define JS_LOG(module, log_level, ...)
    133 #  define JS_LOG_FMT(module, log_level, fmt, ...)
    134 #endif
    135 
    136 #undef JS_LOGGING
    137 
    138 }  // namespace js
    139 
    140 #endif /* _js_vm_Logging_h_ */