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 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:
24 2590463 : BytecodeLabel() : bound_(false), offset_(kInvalidOffset) {}
25 :
26 : bool is_bound() const { return bound_; }
27 : size_t offset() const { return offset_; }
28 :
29 : private:
30 : static const size_t kInvalidOffset = static_cast<size_t>(-1);
31 :
32 : void bind_to(size_t offset) {
33 : DCHECK(!bound_ && offset != kInvalidOffset);
34 2701478 : offset_ = offset;
35 2701478 : bound_ = true;
36 : }
37 :
38 : void set_referrer(size_t offset) {
39 : DCHECK(!bound_ && offset != kInvalidOffset && offset_ == kInvalidOffset);
40 1815233 : offset_ = offset;
41 : }
42 :
43 4516727 : bool is_forward_target() const {
44 4516727 : 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:
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 :
69 : bool is_bound() const {
70 580906 : 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 :
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_
|