bytecode-label.h 2.43 KB
Newer Older
1 2 3 4 5 6 7
// Copyright 2015 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_INTERPRETER_BYTECODE_LABEL_H_
#define V8_INTERPRETER_BYTECODE_LABEL_H_

8 9
#include <algorithm>

10
#include "src/zone/zone-containers.h"
11

12 13 14 15
namespace v8 {
namespace internal {
namespace interpreter {

16 17
class BytecodeArrayBuilder;

18 19 20 21
// A label representing a branch target in a bytecode array. When a
// label is bound, it represents a known position in the bytecode
// array. For labels that are forward references there can be at most
// one reference whilst it is unbound.
22
class V8_EXPORT_PRIVATE BytecodeLabel final {
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
 public:
  BytecodeLabel() : bound_(false), offset_(kInvalidOffset) {}

  bool is_bound() const { return bound_; }
  size_t offset() const { return offset_; }

 private:
  static const size_t kInvalidOffset = static_cast<size_t>(-1);

  void bind_to(size_t offset) {
    DCHECK(!bound_ && offset != kInvalidOffset);
    offset_ = offset;
    bound_ = true;
  }

  void set_referrer(size_t offset) {
    DCHECK(!bound_ && offset != kInvalidOffset && offset_ == kInvalidOffset);
    offset_ = offset;
  }

  bool is_forward_target() const {
    return offset() != kInvalidOffset && !is_bound();
  }

  // There are three states for a label:
  //                    bound_   offset_
  //  UNSET             false    kInvalidOffset
  //  FORWARD_TARGET    false    Offset of referring jump
  //  BACKWARD_TARGET    true    Offset of label in bytecode array when bound
  bool bound_;
  size_t offset_;

55
  friend class BytecodeArrayWriter;
56 57
};

58
// Class representing a branch target of multiple jumps.
59
class V8_EXPORT_PRIVATE BytecodeLabels {
60 61 62 63 64 65 66
 public:
  explicit BytecodeLabels(Zone* zone) : labels_(zone) {}

  BytecodeLabel* New();

  void Bind(BytecodeArrayBuilder* builder);

67 68 69
  void BindToLabel(BytecodeArrayBuilder* builder, const BytecodeLabel& target);

  bool is_bound() const {
70
    bool is_bound = !labels_.empty() && labels_.front().is_bound();
71 72 73 74 75 76 77 78
    DCHECK(!is_bound ||
           std::all_of(labels_.begin(), labels_.end(),
                       [](const BytecodeLabel& l) { return l.is_bound(); }));
    return is_bound;
  }

  bool empty() const { return labels_.empty(); }

79
 private:
80
  ZoneLinkedList<BytecodeLabel> labels_;
81 82 83 84

  DISALLOW_COPY_AND_ASSIGN(BytecodeLabels);
};

85 86 87 88 89
}  // namespace interpreter
}  // namespace internal
}  // namespace v8

#endif  // V8_INTERPRETER_BYTECODE_LABEL_H_