• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 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_INTERPRETER_BYTECODE_LABEL_H_
6 #define V8_INTERPRETER_BYTECODE_LABEL_H_
7 
8 #include <algorithm>
9 
10 #include "src/zone/zone-containers.h"
11 
12 namespace v8 {
13 namespace internal {
14 namespace interpreter {
15 
16 class BytecodeArrayBuilder;
17 
18 // A label representing a branch target in a bytecode array. When a
19 // label is bound, it represents a known position in the bytecode
20 // array. For labels that are forward references there can be at most
21 // one reference whilst it is unbound.
22 class V8_EXPORT_PRIVATE BytecodeLabel final {
23  public:
BytecodeLabel()24   BytecodeLabel() : bound_(false), offset_(kInvalidOffset) {}
25 
is_bound()26   bool is_bound() const { return bound_; }
offset()27   size_t offset() const { return offset_; }
28 
29  private:
30   static const size_t kInvalidOffset = static_cast<size_t>(-1);
31 
bind_to(size_t offset)32   void bind_to(size_t offset) {
33     DCHECK(!bound_ && offset != kInvalidOffset);
34     offset_ = offset;
35     bound_ = true;
36   }
37 
set_referrer(size_t offset)38   void set_referrer(size_t offset) {
39     DCHECK(!bound_ && offset != kInvalidOffset && offset_ == kInvalidOffset);
40     offset_ = offset;
41   }
42 
is_forward_target()43   bool is_forward_target() const {
44     return offset() != kInvalidOffset && !is_bound();
45   }
46 
47   // There are three states for a label:
48   //                    bound_   offset_
49   //  UNSET             false    kInvalidOffset
50   //  FORWARD_TARGET    false    Offset of referring jump
51   //  BACKWARD_TARGET    true    Offset of label in bytecode array when bound
52   bool bound_;
53   size_t offset_;
54 
55   friend class BytecodeArrayWriter;
56 };
57 
58 // Class representing a branch target of multiple jumps.
59 class V8_EXPORT_PRIVATE BytecodeLabels {
60  public:
BytecodeLabels(Zone * zone)61   explicit BytecodeLabels(Zone* zone) : labels_(zone) {}
62 
63   BytecodeLabel* New();
64 
65   void Bind(BytecodeArrayBuilder* builder);
66 
67   void BindToLabel(BytecodeArrayBuilder* builder, const BytecodeLabel& target);
68 
is_bound()69   bool is_bound() const {
70     bool is_bound = !labels_.empty() && labels_.front().is_bound();
71     DCHECK(!is_bound ||
72            std::all_of(labels_.begin(), labels_.end(),
73                        [](const BytecodeLabel& l) { return l.is_bound(); }));
74     return is_bound;
75   }
76 
empty()77   bool empty() const { return labels_.empty(); }
78 
79  private:
80   ZoneLinkedList<BytecodeLabel> labels_;
81 
82   DISALLOW_COPY_AND_ASSIGN(BytecodeLabels);
83 };
84 
85 }  // namespace interpreter
86 }  // namespace internal
87 }  // namespace v8
88 
89 #endif  // V8_INTERPRETER_BYTECODE_LABEL_H_
90