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

Quelle  Disassembler-shared.h   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/. */


#ifndef jit_shared_Disassembler_shared_h
#define jit_shared_Disassembler_shared_h

#include "mozilla/Atomics.h"
#include "mozilla/Attributes.h"

#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>

#include "jstypes.h"  // JS_PUBLIC_API

#if defined(JS_DISASM_ARM) || defined(JS_DISASM_ARM64)
#  define JS_DISASM_SUPPORTED
#endif

namespace js {

class JS_PUBLIC_API Sprinter;

namespace jit {

class Label;

// A wrapper around spew/disassembly functionality.  The disassembler is built
// on a per-instruction disassembler (as in our ARM, ARM64 back-ends) and
// formats labels with meaningful names and literals with meaningful values, if
// the assembler creates documentation (with provided helpers) at appropriate
// points.

class DisassemblerSpew {
#ifdef JS_DISASM_SUPPORTED
  struct Node {
    const Label* key;  // Never dereferenced, only used for its value
    uint32_t value;    // The printable label value
    bool bound;        // If the label has been seen by spewBind()
    Node* next;
  };

  Node* lookup(const Label* key);
  Node* add(const Label* key, uint32_t value);
  bool remove(const Label* key);

  uint32_t probe(const Label* l);
  uint32_t define(const Label* l);
  uint32_t internalResolve(const Label* l);
#endif

  void spewVA(const char* fmt, va_list args) MOZ_FORMAT_PRINTF(2, 0);

 public:
  DisassemblerSpew();
  ~DisassemblerSpew();

#ifdef JS_DISASM_SUPPORTED
  // Set indentation strings.  The spewer retains a reference to s.
  void setLabelIndent(const char* s);
  void setTargetIndent(const char* s);
#endif

  // Set the spew printer, which will always be used if it is set, regardless
  // of whether the system spew channel is enabled or not.  The spewer retains
  // a reference to sp.
  void setPrinter(Sprinter* sp);

  // Return true if disassembly spew is disabled and no additional printer is
  // set.
  bool isDisabled();

  // Format and print text on the spew channel; output is suppressed if spew
  // is disabled.  The output is not indented, and is terminated by a newline.
  void spew(const char* fmt, ...) MOZ_FORMAT_PRINTF(2, 3);

  // Documentation for a label reference.
  struct LabelDoc {
#ifdef JS_DISASM_SUPPORTED
    LabelDoc() : doc(0), bound(false), valid(false) {}
    LabelDoc(uint32_t doc, bool bound) : doc(doc), bound(bound), valid(true) {}
    const uint32_t doc;
    const bool bound;
    const bool valid;
#else
    LabelDoc() = default;
    LabelDoc(uint32_t, bool) {}
#endif
  };

  // Documentation for a literal load.
  struct LiteralDoc {
#ifdef JS_DISASM_SUPPORTED
    enum class Type { Patchable, I32, U32, I64, U64, F32, F64 };
    const Type type;
    union {
      int32_t i32;
      uint32_t u32;
      int64_t i64;
      uint64_t u64;
      float f32;
      double f64;
    } value;
    LiteralDoc() : type(Type::Patchable) {}
    explicit LiteralDoc(int32_t v) : type(Type::I32) { value.i32 = v; }
    explicit LiteralDoc(uint32_t v) : type(Type::U32) { value.u32 = v; }
    explicit LiteralDoc(int64_t v) : type(Type::I64) { value.i64 = v; }
    explicit LiteralDoc(uint64_t v) : type(Type::U64) { value.u64 = v; }
    explicit LiteralDoc(float v) : type(Type::F32) { value.f32 = v; }
    explicit LiteralDoc(double v) : type(Type::F64) { value.f64 = v; }
#else
    LiteralDoc() = default;
    explicit LiteralDoc(int32_t) {}
    explicit LiteralDoc(uint32_t) {}
    explicit LiteralDoc(int64_t) {}
    explicit LiteralDoc(uint64_t) {}
    explicit LiteralDoc(float) {}
    explicit LiteralDoc(double) {}
#endif
  };

  // Reference a label, resolving it to a printable representation.
  //
  // NOTE: The printable representation depends on the state of the label, so
  // if we call resolve() when emitting & disassembling a branch instruction
  // then it should be called before the label becomes Used, if emitting the
  // branch can change the label's state.
  //
  // If the disassembler is not defined this returns a structure that is
  // marked not valid.
  LabelDoc refLabel(const Label* l);

#ifdef JS_DISASM_SUPPORTED
  // Spew the label information previously gathered by refLabel(), at a point
  // where the label is referenced.  The output is indented by targetIndent_
  // and terminated by a newline.
  void spewRef(const LabelDoc& target);

  // Spew the label at the point where the label is bound.  The output is
  // indented by labelIndent_ and terminated by a newline.
  void spewBind(const Label* label);

  // Spew a retarget directive at the point where the retarget is recorded.
  // The output is indented by labelIndent_ and terminated by a newline.
  void spewRetarget(const Label* label, const Label* target);

  // Format a literal value into the buffer.  The buffer is always
  // NUL-terminated even if this chops the formatted value.
  void formatLiteral(const LiteralDoc& doc, char* buffer, size_t bufsize);

  // Print any unbound labels, one per line, with normal label indent and with
  // a comment indicating the label is not defined.  Labels can be referenced
  // but unbound in some legitimate cases, normally for traps.  Printing them
  // reduces confusion.
  void spewOrphans();
#endif

 private:
  Sprinter* printer_;
#ifdef JS_DISASM_SUPPORTED
  const char* labelIndent_;
  const char* targetIndent_;
  uint32_t spewNext_;
  Node* nodes_;
  uint32_t tag_;

  // This global is used to disambiguate concurrently live assemblers, see
  // comments in Disassembler-shared.cpp for why this is desirable.
  //
  // The variable is atomic to avoid any kind of complaint from thread
  // sanitizers etc.  However, trying to look at disassembly without using
  // --no-threads is basically insane, so you can ignore the multi-threading
  // implications here.
  static mozilla::Atomic<uint32_t> counter_;
#endif
};

}  // namespace jit
}  // namespace js

#endif  // jit_shared_Disassembler_shared_h

Messung V0.5
C=91 H=97 G=93

¤ Dauer der Verarbeitung: 0.11 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.