Line data Source code
1 : // Copyright 2017 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_LABEL_H_
6 : #define V8_LABEL_H_
7 :
8 : #include "src/base/macros.h"
9 :
10 : namespace v8 {
11 : namespace internal {
12 :
13 : // -----------------------------------------------------------------------------
14 : // Labels represent pc locations; they are typically jump or call targets.
15 : // After declaration, a label can be freely used to denote known or (yet)
16 : // unknown pc location. Assembler::bind() is used to bind a label to the
17 : // current pc. A label can be bound only once.
18 :
19 : class Label {
20 : public:
21 : enum Distance {
22 : kNear, // near jump: 8 bit displacement (signed)
23 : kFar // far jump: 32 bit displacement (signed)
24 : };
25 :
26 32392923 : Label() = default;
27 :
28 : // On ARM64, the Assembler keeps track of pointers to Labels to resolve
29 : // branches to distant targets. Copying labels would confuse the Assembler.
30 : // On other platforms, allow move construction.
31 : #if !V8_TARGET_ARCH_ARM64
32 : // In debug builds, the old Label has to be cleared in order to avoid a DCHECK
33 : // failure in it's destructor.
34 : #ifdef DEBUG
35 : Label(Label&& other) V8_NOEXCEPT { *this = std::move(other); }
36 : Label& operator=(Label&& other) V8_NOEXCEPT {
37 : pos_ = other.pos_;
38 : near_link_pos_ = other.near_link_pos_;
39 : other.Unuse();
40 : other.UnuseNear();
41 : return *this;
42 : }
43 : #else
44 : Label(Label&&) V8_NOEXCEPT = default;
45 : Label& operator=(Label&&) V8_NOEXCEPT = default;
46 : #endif
47 : #endif
48 :
49 : #ifdef DEBUG
50 : V8_INLINE ~Label() {
51 : DCHECK(!is_linked());
52 : DCHECK(!is_near_linked());
53 : }
54 : #endif
55 :
56 82169 : V8_INLINE void Unuse() { pos_ = 0; }
57 708301 : V8_INLINE void UnuseNear() { near_link_pos_ = 0; }
58 :
59 28720961 : V8_INLINE bool is_bound() const { return pos_ < 0; }
60 : V8_INLINE bool is_unused() const { return pos_ == 0 && near_link_pos_ == 0; }
61 50887054 : V8_INLINE bool is_linked() const { return pos_ > 0; }
62 40205568 : V8_INLINE bool is_near_linked() const { return near_link_pos_ > 0; }
63 :
64 : // Returns the position of bound or linked labels. Cannot be used
65 : // for unused labels.
66 : int pos() const {
67 22925798 : if (pos_ < 0) return -pos_ - 1;
68 17880056 : if (pos_ > 0) return pos_ - 1;
69 0 : UNREACHABLE();
70 : }
71 :
72 712917 : int near_link_pos() const { return near_link_pos_ - 1; }
73 :
74 : private:
75 : // pos_ encodes both the binding state (via its sign)
76 : // and the binding position (via its value) of a label.
77 : //
78 : // pos_ < 0 bound label, pos() returns the jump target position
79 : // pos_ == 0 unused label
80 : // pos_ > 0 linked label, pos() returns the last reference position
81 : int pos_ = 0;
82 :
83 : // Behaves like |pos_| in the "> 0" case, but for near jumps to this label.
84 : int near_link_pos_ = 0;
85 :
86 : void bind_to(int pos) {
87 39107282 : pos_ = -pos - 1;
88 : DCHECK(is_bound());
89 : }
90 : void link_to(int pos, Distance distance = kFar) {
91 : if (distance == kNear) {
92 712916 : near_link_pos_ = pos + 1;
93 : DCHECK(is_near_linked());
94 : } else {
95 17897697 : pos_ = pos + 1;
96 : DCHECK(is_linked());
97 : }
98 : }
99 :
100 : friend class Assembler;
101 : friend class Displacement;
102 : friend class RegExpMacroAssemblerIrregexp;
103 :
104 : // Disallow copy construction and assignment, but allow move construction and
105 : // move assignment on selected platforms (see above).
106 : DISALLOW_COPY_AND_ASSIGN(Label);
107 : };
108 :
109 : } // namespace internal
110 : } // namespace v8
111 :
112 : #endif // V8_LABEL_H_
|