tor-browser

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

Label.h (3224B)


      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 #ifndef jit_Label_h
      8 #define jit_Label_h
      9 
     10 #include "mozilla/Assertions.h"
     11 
     12 #include <stdint.h>
     13 
     14 namespace js {
     15 namespace jit {
     16 
     17 struct LabelBase {
     18 private:
     19  // We use uint32_t instead of bool to ensure MSVC packs these fields
     20  // correctly.
     21  uint32_t bound_ : 1;
     22 
     23  // offset_ < INVALID_OFFSET means that the label is either bound or has
     24  // incoming uses and needs to be bound.
     25  uint32_t offset_ : 31;
     26 
     27  void operator=(const LabelBase& label) = delete;
     28 
     29 #if defined(JS_CODEGEN_MIPS64) || defined(JS_CODEGEN_LOONG64) || \
     30    defined(JS_CODEGEN_RISCV64)
     31 public:
     32 #endif
     33  static const uint32_t INVALID_OFFSET = 0x7fffffff;  // UINT31_MAX.
     34 
     35 public:
     36  LabelBase() : bound_(false), offset_(INVALID_OFFSET) {}
     37 
     38  // If the label is bound, all incoming edges have been patched and any
     39  // future incoming edges will be immediately patched.
     40  bool bound() const { return bound_; }
     41  int32_t offset() const {
     42    MOZ_ASSERT(bound() || used());
     43    return offset_;
     44  }
     45  // Returns whether the label is not bound, but has incoming uses.
     46  bool used() const { return !bound() && offset_ < INVALID_OFFSET; }
     47  // Binds the label, fixing its final position in the code stream.
     48  void bind(int32_t offset) {
     49    MOZ_ASSERT(!bound());
     50    MOZ_ASSERT(offset >= 0);
     51    MOZ_ASSERT(uint32_t(offset) < INVALID_OFFSET);
     52    offset_ = offset;
     53    bound_ = true;
     54    MOZ_ASSERT(offset_ == offset, "offset fits in 31 bits");
     55  }
     56  // Marks the label as neither bound nor used.
     57  void reset() {
     58    offset_ = INVALID_OFFSET;
     59    bound_ = false;
     60  }
     61  // Sets the label's latest used position.
     62  void use(int32_t offset) {
     63    MOZ_ASSERT(!bound());
     64    MOZ_ASSERT(offset >= 0);
     65    MOZ_ASSERT(uint32_t(offset) < INVALID_OFFSET);
     66    offset_ = offset;
     67    MOZ_ASSERT(offset_ == offset, "offset fits in 31 bits");
     68  }
     69 };
     70 
     71 // A label represents a position in an assembly buffer that may or may not have
     72 // already been generated. Labels can either be "bound" or "unbound", the
     73 // former meaning that its position is known and the latter that its position
     74 // is not yet known.
     75 //
     76 // A jump to an unbound label adds that jump to the label's incoming queue. A
     77 // jump to a bound label automatically computes the jump distance. The process
     78 // of binding a label automatically corrects all incoming jumps.
     79 class Label : public LabelBase {
     80 public:
     81 #ifdef DEBUG
     82  ~Label();
     83 #endif
     84 };
     85 
     86 static_assert(sizeof(Label) == sizeof(uint32_t),
     87              "Label should have same size as uint32_t");
     88 
     89 // Label's destructor asserts that if it has been used it has also been bound.
     90 // In the case long-lived labels, however, failed compilation (e.g. OOM) will
     91 // trigger this failure innocuously. This Label silences the assertion.
     92 class NonAssertingLabel : public Label {
     93 public:
     94 #ifdef DEBUG
     95  ~NonAssertingLabel() {
     96    if (used()) {
     97      bind(0);
     98    }
     99  }
    100 #endif
    101 };
    102 
    103 }  // namespace jit
    104 }  // namespace js
    105 
    106 #endif  // jit_Label_h