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 <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 loop header in a bytecode array. It is bound before
19 : // the jump is seen, so its position is always known by the time the jump is
20 : // reached.
21 : class V8_EXPORT_PRIVATE BytecodeLoopHeader final {
22 : public:
23 278400 : BytecodeLoopHeader() : offset_(kInvalidOffset) {}
24 :
25 : size_t offset() const {
26 : DCHECK_NE(offset_, kInvalidOffset);
27 254099 : return offset_;
28 : }
29 :
30 : private:
31 : static const size_t kInvalidOffset = static_cast<size_t>(-1);
32 :
33 : void bind_to(size_t offset) {
34 : DCHECK_NE(offset, kInvalidOffset);
35 : DCHECK_EQ(offset_, kInvalidOffset);
36 262480 : offset_ = offset;
37 : }
38 :
39 : // The bytecode offset of the loop header.
40 : size_t offset_;
41 :
42 : friend class BytecodeArrayWriter;
43 : };
44 :
45 : // A label representing a forward branch target in a bytecode array. When a
46 : // label is bound, it represents a known position in the bytecode array. A label
47 : // can only have at most one referrer jump.
48 : class V8_EXPORT_PRIVATE BytecodeLabel final {
49 : public:
50 1865502 : BytecodeLabel() : bound_(false), jump_offset_(kInvalidOffset) {}
51 :
52 : bool is_bound() const { return bound_; }
53 : size_t jump_offset() const {
54 : DCHECK_NE(jump_offset_, kInvalidOffset);
55 : return jump_offset_;
56 : }
57 :
58 1 : bool has_referrer_jump() const { return jump_offset_ != kInvalidOffset; }
59 :
60 : private:
61 : static const size_t kInvalidOffset = static_cast<size_t>(-1);
62 :
63 : void bind() {
64 : DCHECK(!bound_);
65 1823454 : bound_ = true;
66 : }
67 :
68 : void set_referrer(size_t offset) {
69 : DCHECK(!bound_);
70 : DCHECK_NE(offset, kInvalidOffset);
71 : DCHECK_EQ(jump_offset_, kInvalidOffset);
72 1823469 : jump_offset_ = offset;
73 : }
74 :
75 : // Set when the label is bound (i.e. the start of the target basic block).
76 : bool bound_;
77 : // Set when the jump referrer is set (i.e. the location of the jump).
78 : size_t jump_offset_;
79 :
80 : friend class BytecodeArrayWriter;
81 : };
82 :
83 : // Class representing a branch target of multiple jumps.
84 8146625 : class V8_EXPORT_PRIVATE BytecodeLabels {
85 : public:
86 8146441 : explicit BytecodeLabels(Zone* zone) : labels_(zone), is_bound_(false) {}
87 :
88 : BytecodeLabel* New();
89 :
90 : void Bind(BytecodeArrayBuilder* builder);
91 :
92 : bool is_bound() const {
93 : DCHECK_IMPLIES(
94 : is_bound_,
95 : std::all_of(labels_.begin(), labels_.end(), [](const BytecodeLabel& l) {
96 : return !l.has_referrer_jump() || l.is_bound();
97 : }));
98 : return is_bound_;
99 : }
100 :
101 : bool empty() const { return labels_.empty(); }
102 :
103 : private:
104 : ZoneLinkedList<BytecodeLabel> labels_;
105 : bool is_bound_;
106 :
107 : DISALLOW_COPY_AND_ASSIGN(BytecodeLabels);
108 : };
109 :
110 : } // namespace interpreter
111 : } // namespace internal
112 : } // namespace v8
113 :
114 : #endif // V8_INTERPRETER_BYTECODE_LABEL_H_
|