Home | History | Annotate | Download | only in src
      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 { kNear, kFar };
     22 
     23   INLINE(Label()) {
     24     Unuse();
     25     UnuseNear();
     26   }
     27 
     28   INLINE(~Label()) {
     29     DCHECK(!is_linked());
     30     DCHECK(!is_near_linked());
     31   }
     32 
     33   INLINE(void Unuse()) { pos_ = 0; }
     34   INLINE(void UnuseNear()) { near_link_pos_ = 0; }
     35 
     36   INLINE(bool is_bound() const) { return pos_ < 0; }
     37   INLINE(bool is_unused() const) { return pos_ == 0 && near_link_pos_ == 0; }
     38   INLINE(bool is_linked() const) { return pos_ > 0; }
     39   INLINE(bool is_near_linked() const) { return near_link_pos_ > 0; }
     40 
     41   // Returns the position of bound or linked labels. Cannot be used
     42   // for unused labels.
     43   int pos() const {
     44     if (pos_ < 0) return -pos_ - 1;
     45     if (pos_ > 0) return pos_ - 1;
     46     UNREACHABLE();
     47     return 0;
     48   }
     49 
     50   int near_link_pos() const { return near_link_pos_ - 1; }
     51 
     52  private:
     53   // pos_ encodes both the binding state (via its sign)
     54   // and the binding position (via its value) of a label.
     55   //
     56   // pos_ <  0  bound label, pos() returns the jump target position
     57   // pos_ == 0  unused label
     58   // pos_ >  0  linked label, pos() returns the last reference position
     59   int pos_;
     60 
     61   // Behaves like |pos_| in the "> 0" case, but for near jumps to this label.
     62   int near_link_pos_;
     63 
     64   void bind_to(int pos) {
     65     pos_ = -pos - 1;
     66     DCHECK(is_bound());
     67   }
     68   void link_to(int pos, Distance distance = kFar) {
     69     if (distance == kNear) {
     70       near_link_pos_ = pos + 1;
     71       DCHECK(is_near_linked());
     72     } else {
     73       pos_ = pos + 1;
     74       DCHECK(is_linked());
     75     }
     76   }
     77 
     78   friend class Assembler;
     79   friend class Displacement;
     80   friend class RegExpMacroAssemblerIrregexp;
     81 
     82 #if V8_TARGET_ARCH_ARM64
     83   // On ARM64, the Assembler keeps track of pointers to Labels to resolve
     84   // branches to distant targets. Copying labels would confuse the Assembler.
     85   DISALLOW_COPY_AND_ASSIGN(Label);  // NOLINT
     86 #endif
     87 };
     88 
     89 }  // namespace internal
     90 }  // namespace v8
     91 
     92 #endif  // V8_LABEL_H_
     93