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