Bug 1867190 - Add prefs for PHC probablities r=glandium
[gecko.git] / js / src / jit / Label.h
blobbf78d3c5b87a09abc2ca3c5d4bf4f152fab31419
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/. */
7 #ifndef jit_Label_h
8 #define jit_Label_h
10 #include "mozilla/Assertions.h"
12 #include <stdint.h>
14 namespace js {
15 namespace jit {
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;
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;
27 void operator=(const LabelBase& label) = delete;
29 #if defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64) || \
30 defined(JS_CODEGEN_LOONG64) || defined(JS_CODEGEN_RISCV64)
31 public:
32 #endif
33 static const uint32_t INVALID_OFFSET = 0x7fffffff; // UINT31_MAX.
35 public:
36 LabelBase() : bound_(false), offset_(INVALID_OFFSET) {}
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_;
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");
56 // Marks the label as neither bound nor used.
57 void reset() {
58 offset_ = INVALID_OFFSET;
59 bound_ = false;
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");
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.
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
86 static_assert(sizeof(Label) == sizeof(uint32_t),
87 "Label should have same size as uint32_t");
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);
100 #endif
103 } // namespace jit
104 } // namespace js
106 #endif // jit_Label_h