Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/js/src/util/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 7 kB image not shown  

Quelle  StructuredSpewer.cpp   Sprache: C

 
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim: set ts=8 sts=2 et sw=2 tw=80:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#ifdef JS_STRUCTURED_SPEW

#  include "util/StructuredSpewer.h"

#  include "mozilla/Sprintf.h"

#  include "util/GetPidProvider.h"  // getpid()
#  include "util/Text.h"
#  include "vm/JSContext.h"
#  include "vm/JSScript.h"

using namespace js;

const StructuredSpewer::NameArray StructuredSpewer::names_ = {
#  define STRUCTURED_CHANNEL(name) #name,
    STRUCTURED_CHANNEL_LIST(STRUCTURED_CHANNEL)
#  undef STRUCTURED_CHANNEL
};

// Choose a sensible default spew directory.
//
// The preference here is to use the current working directory,
// except on Android.
#  ifndef DEFAULT_SPEW_DIRECTORY
#    if defined(_WIN32)
#      define DEFAULT_SPEW_DIRECTORY "."
#    elif defined(__ANDROID__)
#      define DEFAULT_SPEW_DIRECTORY "/data/local/tmp"
#    else
#      define DEFAULT_SPEW_DIRECTORY "."
#    endif
#  endif

bool StructuredSpewer::ensureInitializationAttempted() {
  if (!outputInitializationAttempted_) {
    char filename[2048] = {0};
    // For ease of use with Treeherder
    if (getenv("SPEW_UPLOAD") && getenv("MOZ_UPLOAD_DIR")) {
      SprintfLiteral(filename, "%s/spew_output", getenv("MOZ_UPLOAD_DIR"));
    } else if (getenv("SPEW_FILE")) {
      SprintfLiteral(filename, "%s", getenv("SPEW_FILE"));
    } else {
      SprintfLiteral(filename, "%s/spew_output", DEFAULT_SPEW_DIRECTORY);
    }
    tryToInitializeOutput(filename);
    // We can't use the intialization state of the Fprinter, as it is not
    // marked as initialized in a case where we cannot open the output, so
    // we track the attempt separately.
    outputInitializationAttempted_ = true;
  }

  return json_.isSome();
}

void StructuredSpewer::tryToInitializeOutput(const char* path) {
  static mozilla::Atomic<uint32_t, mozilla::ReleaseAcquire> threadCounter;

  char suffix_path[2048] = {0};
  SprintfLiteral(suffix_path, "%s.%d.%u", path, getpid(), threadCounter++);

  if (!output_.init(suffix_path)) {
    // Returning here before we've emplaced the JSONPrinter
    // means this is effectively disabled, but fail earlier
    // we also disable the channel.
    selectedChannel_.disableAllChannels();
    return;
  }

  // These logs are structured as a JSON array.
  json_.emplace(output_);
  json_->beginList();
}

// Treat pattern like a glob, and return true if pattern exists
// in the script's name or filename or line number.
//
// This is the most basic matching I can imagine
static bool MatchJSScript(JSScript* script, const char* pattern) {
  if (!pattern) {
    return false;
  }

  char signature[2048] = {0};
  SprintfLiteral(signature, "%s:%u:%u", script->filename(), script->lineno(),
                 script->column().oneOriginValue());

  // Trivial containment match.
  char* result = strstr(signature, pattern);

  return result != nullptr;
}

bool StructuredSpewer::enabled(JSScript* script) {
  if (spewingEnabled_ == 0) {
    return false;
  }

  static const char* pattern = getenv("SPEW_FILTER");
  if (!pattern || MatchJSScript(script, pattern)) {
    return true;
  }
  return false;
}

bool StructuredSpewer::enabled(JSContext* cx, const JSScript* script,
                               SpewChannel channel) const {
  if (script && !script->spewEnabled()) {
    return false;
  }
  return cx->spewer().enabled(channel);
}

// Attempt to setup a common header for objects based on script/channel.
//
// Returns true if the spewer is prepared for more input
void StructuredSpewer::startObject(JSContext* cx, const JSScript* script,
                                   SpewChannel channel) {
  MOZ_ASSERT(json_.isSome());

  JSONPrinter& json = json_.ref();

  json.beginObject();
  json.property("channel", getName(channel));
  if (script) {
    json.beginObjectProperty("location");
    json.property("filename", script->filename());
    json.property("line", script->lineno());
    json.property("column", script->column().oneOriginValue());
    json.endObject();
  }
}

/* static */
void StructuredSpewer::spew(JSContext* cx, SpewChannel channel, const char* fmt,
                            ...) {
  // Because we don't have a script here, use the singleton's
  // filter to determine if the channel is active.
  if (!cx->spewer().enabled(channel)) {
    return;
  }

  if (!cx->spewer().ensureInitializationAttempted()) {
    return;
  }

  va_list ap;
  va_start(ap, fmt);

  MOZ_ASSERT(cx->spewer().json_.isSome());

  JSONPrinter& json = cx->spewer().json_.ref();

  json.beginObject();
  json.property("channel", getName(channel));
  json.formatPropertyVA("message", fmt, ap);
  json.endObject();

  va_end(ap);
}

// Currently uses the exact spew flag representation as text.
void StructuredSpewer::parseSpewFlags(const char* flags) {
#  define CHECK_CHANNEL(name)                            \
    if (ContainsFlag(flags, #name)) {                    \
      selectedChannel_.enableChannel(SpewChannel::name); \
      break;                                             \
    }

  do {
    STRUCTURED_CHANNEL_LIST(CHECK_CHANNEL)
  } while (false);

#  undef CHECK_CHANNEL

  if (ContainsFlag(flags, "AtStartup")) {
    enableSpewing();
  }

  if (ContainsFlag(flags, "help")) {
    // clang-format off
    printf(
      "\n"
      "usage: SPEW=option,option,... where options can be:\n"
      "\n"
      " help Dump this help message\n"
      " channel Enable the selected channel from below, if\n"
      " more than one channel is specified, then the\n"
      " channel will be set whichever specified filter\n"
      " comes first in STRUCTURED_CHANNEL_LIST.\n"
      " AtStartup Enable spewing at browser startup instead\n"
      " of when gecko profiling starts."
      "\n"
      " Channels: \n"
      "\n"
      // List Channels
      " BaselineICStats Dump the IC Entry counters during Ion analysis\n"
      " CacheIRHealthReport Dump the CacheIR information and associated rating\n"
      // End Channel list
      "\n\n"
      "By default output goes to a file called spew_output.$PID.$THREAD\n"
      "\n"
      "Further control of the spewer can be accomplished with the below\n"
      "environment variables:\n"
      "\n"
      " SPEW_FILE: Selects the file to write to. An absolute path.\n"
      "\n"
      " SPEW_FILTER: A string which is matched against 'signature'\n"
      " constructed from a JSScript, currently connsisting of \n"
      " filename:line:col.\n"
      "\n"
      " A JSScript matches the filter string is found in the\n"
      " signature\n"
      "\n"
      " SPEW_UPLOAD: If this variable is set as well as MOZ_UPLOAD_DIR,\n"
      " output goes to $MOZ_UPLOAD_DIR/spew_output* to ease usage\n"
      " with Treeherder.\n"

    );
    // clang-format on
    exit(0);
  }
}

AutoStructuredSpewer::AutoStructuredSpewer(JSContext* cx, SpewChannel channel,
                                           JSScript* script)
    : printer_(mozilla::Nothing()) {
  if (!cx->spewer().enabled(cx, script, channel)) {
    return;
  }

  if (!cx->spewer().ensureInitializationAttempted()) {
    return;
  }

  cx->spewer().startObject(cx, script, channel);
  printer_.emplace(&cx->spewer().json_.ref());
}

AutoSpewChannel::AutoSpewChannel(JSContext* cx, SpewChannel channel,
                                 JSScript* script)
    : cx_(cx) {
  if (!cx->spewer().enabled(cx, script, channel)) {
    wasChannelAutoSet = cx->spewer().selectedChannel_.enableChannel(channel);
  }
}

AutoSpewChannel::~AutoSpewChannel() {
  if (wasChannelAutoSet) {
    cx_->spewer().selectedChannel_.disableAllChannels();
  }
}

#endif

Messung V0.5
C=94 H=98 G=95

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.