aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/codegen/label.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/codegen/label.h')
-rw-r--r--deps/v8/src/codegen/label.h112
1 files changed, 112 insertions, 0 deletions
diff --git a/deps/v8/src/codegen/label.h b/deps/v8/src/codegen/label.h
new file mode 100644
index 0000000000..430958d190
--- /dev/null
+++ b/deps/v8/src/codegen/label.h
@@ -0,0 +1,112 @@
+// Copyright 2017 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_CODEGEN_LABEL_H_
+#define V8_CODEGEN_LABEL_H_
+
+#include "src/base/macros.h"
+
+namespace v8 {
+namespace internal {
+
+// -----------------------------------------------------------------------------
+// Labels represent pc locations; they are typically jump or call targets.
+// After declaration, a label can be freely used to denote known or (yet)
+// unknown pc location. Assembler::bind() is used to bind a label to the
+// current pc. A label can be bound only once.
+
+class Label {
+ public:
+ enum Distance {
+ kNear, // near jump: 8 bit displacement (signed)
+ kFar // far jump: 32 bit displacement (signed)
+ };
+
+ Label() = default;
+
+// On ARM64, the Assembler keeps track of pointers to Labels to resolve
+// branches to distant targets. Copying labels would confuse the Assembler.
+// On other platforms, allow move construction.
+#if !V8_TARGET_ARCH_ARM64
+// In debug builds, the old Label has to be cleared in order to avoid a DCHECK
+// failure in it's destructor.
+#ifdef DEBUG
+ Label(Label&& other) V8_NOEXCEPT { *this = std::move(other); }
+ Label& operator=(Label&& other) V8_NOEXCEPT {
+ pos_ = other.pos_;
+ near_link_pos_ = other.near_link_pos_;
+ other.Unuse();
+ other.UnuseNear();
+ return *this;
+ }
+#else
+ Label(Label&&) V8_NOEXCEPT = default;
+ Label& operator=(Label&&) V8_NOEXCEPT = default;
+#endif
+#endif
+
+#ifdef DEBUG
+ V8_INLINE ~Label() {
+ DCHECK(!is_linked());
+ DCHECK(!is_near_linked());
+ }
+#endif
+
+ V8_INLINE void Unuse() { pos_ = 0; }
+ V8_INLINE void UnuseNear() { near_link_pos_ = 0; }
+
+ V8_INLINE bool is_bound() const { return pos_ < 0; }
+ V8_INLINE bool is_unused() const { return pos_ == 0 && near_link_pos_ == 0; }
+ V8_INLINE bool is_linked() const { return pos_ > 0; }
+ V8_INLINE bool is_near_linked() const { return near_link_pos_ > 0; }
+
+ // Returns the position of bound or linked labels. Cannot be used
+ // for unused labels.
+ int pos() const {
+ if (pos_ < 0) return -pos_ - 1;
+ if (pos_ > 0) return pos_ - 1;
+ UNREACHABLE();
+ }
+
+ int near_link_pos() const { return near_link_pos_ - 1; }
+
+ private:
+ // pos_ encodes both the binding state (via its sign)
+ // and the binding position (via its value) of a label.
+ //
+ // pos_ < 0 bound label, pos() returns the jump target position
+ // pos_ == 0 unused label
+ // pos_ > 0 linked label, pos() returns the last reference position
+ int pos_ = 0;
+
+ // Behaves like |pos_| in the "> 0" case, but for near jumps to this label.
+ int near_link_pos_ = 0;
+
+ void bind_to(int pos) {
+ pos_ = -pos - 1;
+ DCHECK(is_bound());
+ }
+ void link_to(int pos, Distance distance = kFar) {
+ if (distance == kNear) {
+ near_link_pos_ = pos + 1;
+ DCHECK(is_near_linked());
+ } else {
+ pos_ = pos + 1;
+ DCHECK(is_linked());
+ }
+ }
+
+ friend class Assembler;
+ friend class Displacement;
+ friend class RegExpMacroAssemblerIrregexp;
+
+ // Disallow copy construction and assignment, but allow move construction and
+ // move assignment on selected platforms (see above).
+ DISALLOW_COPY_AND_ASSIGN(Label);
+};
+
+} // namespace internal
+} // namespace v8
+
+#endif // V8_CODEGEN_LABEL_H_