v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
control-flow-builders.cc
Go to the documentation of this file.
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
7
8namespace v8 {
9namespace internal {
10namespace interpreter {
11
12
21
25
27 builder()->Jump(sites->New());
28}
29
34
39
43
45 Register index,
46 Register cache_length) {
47 builder()->JumpIfForInDone(sites->New(), index, cache_length);
48}
49
54
56 // Jumps from before the loop header into the loop violate ordering
57 // requirements of bytecode basic blocks. The only entry into a loop
58 // must be the loop header. Surely breaks is okay? Not if nested
59 // and misplaced between the headers.
63}
64
70
71void LoopBuilder::JumpToHeader(int loop_depth, LoopBuilder* const parent_loop) {
73 if (parent_loop &&
74 loop_header_.offset() == parent_loop->loop_header_.offset()) {
75 // TurboFan can't cope with multiple loops that have the same loop header
76 // bytecode offset. If we have an inner loop with the same header offset
77 // than its parent loop, we do not create a JumpLoop bytecode. Instead, we
78 // Jump to our parent's JumpToHeader which in turn can be a JumpLoop or, iff
79 // they are a nested inner loop too, a Jump to its parent's JumpToHeader.
80 parent_loop->JumpToLoopEnd();
81 } else {
82 // Pass the proper loop depth to the backwards branch for triggering OSR.
83 // For purposes of OSR, the loop depth is capped at `kMaxOsrUrgency - 1`.
84 // Once that urgency is reached, all loops become OSR candidates.
85 //
86 // The loop must have closed form, i.e. all loop elements are within the
87 // loop, the loop header precedes the body and next elements in the loop.
88 int slot_index = feedback_vector_spec_->AddJumpLoopSlot().ToInt();
90 &loop_header_, std::min(loop_depth, FeedbackVector::kMaxOsrUrgency - 1),
91 source_position_, slot_index);
92 }
93}
94
96
98
100#ifdef DEBUG
101 for (auto site : case_sites_) {
102 DCHECK(!site.has_referrer_jump() || site.is_bound());
103 }
104#endif
105}
106
108 CaseClause* clause) {
109 builder()->Bind(jump_table_, case_value);
110 BuildBlockCoverage(clause);
111}
112
114 CaseClause* clause) {
115 builder()->Bind(&case_sites_.at(index));
116 BuildBlockCoverage(clause);
117}
118
123
124// Precondition: tag is in the accumulator
126 int min_case, int max_case, std::map<int, CaseClause*>& covered_cases) {
129 for (int j = min_case; j <= max_case; ++j) {
130 if (covered_cases.find(j) == covered_cases.end()) {
131 this->BindCaseTargetForJumpTable(j, nullptr);
132 }
133 }
134}
135
140
142
147
154
158
159
170
172
179
183
184
188
189
193
194
199
208
210 // Nothing to be done here.
211}
212
215#ifdef DEBUG
217
218 for (auto* label : then_labels_list_) {
219 DCHECK(label->empty() || label->is_bound());
220 }
221
222 for (auto* label : else_labels_list_) {
223 DCHECK(label->empty() || label->is_bound());
224 }
225#endif
226}
227
231
240
249
253
257
258 // IfStatement requires a continuation counter, Conditional does not (as it
259 // can only contain expressions).
260 if (block_coverage_builder_ != nullptr && node_->IsIfStatement()) {
263 }
264}
265
267 DCHECK(end_labels_.empty()); // May only be called once.
269}
270
277
284
285} // namespace interpreter
286} // namespace internal
287} // namespace v8
std::map< int, CaseClause * > covered_cases
static constexpr int kMaxOsrUrgency
void EmitJumpIfForInDone(BytecodeLabels *labels, Register index, Register cache_length)
void EmitJumpIfTrue(BytecodeArrayBuilder::ToBooleanMode mode, BytecodeLabels *labels)
void EmitJumpIfFalse(BytecodeArrayBuilder::ToBooleanMode mode, BytecodeLabels *labels)
BytecodeArrayBuilder & JumpIfForInDone(BytecodeLabel *label, Register index, Register cache_length)
BytecodeArrayBuilder & MarkTryEnd(int handler_id)
BytecodeArrayBuilder & JumpIfFalse(ToBooleanMode mode, BytecodeLabel *label)
BytecodeArrayBuilder & MarkTryBegin(int handler_id, Register context)
BytecodeArrayBuilder & Bind(BytecodeLabel *label)
BytecodeArrayBuilder & JumpIfUndefined(BytecodeLabel *label)
BytecodeArrayBuilder & SwitchOnSmiNoFeedback(BytecodeJumpTable *jump_table)
BytecodeArrayBuilder & JumpIfTrue(ToBooleanMode mode, BytecodeLabel *label)
BytecodeArrayBuilder & MarkHandler(int handler_id, HandlerTable::CatchPrediction will_catch)
BytecodeArrayBuilder & JumpLoop(BytecodeLoopHeader *loop_header, int loop_depth, int position, int feedback_slot)
BytecodeArrayBuilder & Jump(BytecodeLabel *label)
void Bind(BytecodeArrayBuilder *builder)
void JumpToHeader(int loop_depth, LoopBuilder *const parent_loop)
void BindCaseTargetForJumpTable(int case_value, CaseClause *clause)
void BindCaseTargetForCompareJump(int index, CaseClause *clause)
void JumpToCaseIfTrue(BytecodeArrayBuilder::ToBooleanMode mode, int index)
void EmitJumpTableIfExists(int min_case, int max_case, std::map< int, CaseClause * > &covered_cases)
Label label
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_LT(v1, v2)
Definition logging.h:489