v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
bytecode-analysis.h
Go to the documentation of this file.
1// Copyright 2016 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_COMPILER_BYTECODE_ANALYSIS_H_
6#define V8_COMPILER_BYTECODE_ANALYSIS_H_
7
8#include <optional>
9
11#include "src/handles/handles.h"
14#include "src/utils/utils.h"
16
17namespace v8 {
18namespace internal {
19
20class BytecodeArray;
21
22namespace compiler {
23
25 public:
26 BytecodeLoopAssignments(int parameter_count, int register_count, Zone* zone);
27
28 void Add(interpreter::Register r);
29 void AddList(interpreter::Register r, uint32_t count);
30 void Union(const BytecodeLoopAssignments& other);
31
32 bool ContainsParameter(int index) const;
33 bool ContainsLocal(int index) const;
34
35 int parameter_count() const { return parameter_count_; }
36 int local_count() const { return bit_vector_->length() - parameter_count_; }
37
38 private:
41};
42
43// Jump targets for resuming a suspended generator.
45 public:
46 // Create a resume jump target representing an actual resume.
47 static ResumeJumpTarget Leaf(int suspend_id, int target_offset);
48
49 // Create a resume jump target at a loop header, which will have another
50 // resume jump after the loop header is crossed.
51 static ResumeJumpTarget AtLoopHeader(int loop_header_offset,
52 const ResumeJumpTarget& next);
53
54 int suspend_id() const { return suspend_id_; }
55 int target_offset() const { return target_offset_; }
56 bool is_leaf() const { return target_offset_ == final_target_offset_; }
57
58 private:
59 // The suspend id of the resume.
61 // The target offset of this resume jump.
63 // The final offset of this resume, which may be across multiple jumps.
65
66 ResumeJumpTarget(int suspend_id, int target_offset, int final_target_offset);
67};
68
70 public:
71 LoopInfo(int parent_offset, int loop_start, int loop_end, int parameter_count,
72 int register_count, Zone* zone)
73 : parent_offset_(parent_offset),
74 loop_start_(loop_start),
75 loop_end_(loop_end),
76 assignments_(parameter_count, register_count, zone),
77 resume_jump_targets_(zone) {}
78
79 int parent_offset() const { return parent_offset_; }
80 int loop_start() const { return loop_start_; }
81 int loop_end() const { return loop_end_; }
82 bool resumable() const { return resumable_; }
83 void mark_resumable() { resumable_ = true; }
84 bool innermost() const { return innermost_; }
85 void mark_not_innermost() { innermost_ = false; }
86
87 bool Contains(int offset) const {
88 return offset >= loop_start_ && offset < loop_end_;
89 }
90
92 return resume_jump_targets_;
93 }
94 void AddResumeTarget(const ResumeJumpTarget& target) {
95 resume_jump_targets_.push_back(target);
96 }
97
98 BytecodeLoopAssignments& assignments() { return assignments_; }
99 const BytecodeLoopAssignments& assignments() const { return assignments_; }
100
101 private:
102 // The offset to the parent loop, or -1 if there is no parent.
106 bool resumable_ = false;
107 bool innermost_ = true;
110};
111
112// Analyze the bytecodes to find the loop ranges, loop nesting, loop assignments
113// and liveness. NOTE: The broker/serializer relies on the fact that an
114// analysis for OSR (osr_bailout_id is not None) subsumes an analysis for
115// non-OSR (osr_bailout_id is None).
117 public:
118 BytecodeAnalysis(Handle<BytecodeArray> bytecode_array, Zone* zone,
119 BytecodeOffset osr_bailout_id, bool analyze_liveness);
122
123 // Return true if the given offset is a loop header
124 bool IsLoopHeader(int offset) const;
125 // Get the loop header offset of the containing loop for arbitrary
126 // {offset}, or -1 if the {offset} is not inside any loop.
127 int GetLoopOffsetFor(int offset) const;
128 // Get the loop end offset given the header offset of an innermost loop
129 int GetLoopEndOffsetForInnermost(int header_offset) const;
130 // Get the loop info of the loop header at {header_offset}.
131 const LoopInfo& GetLoopInfoFor(int header_offset) const;
132 // Try to get the loop info of the loop header at {header_offset}, returning
133 // null if there isn't any.
134 const LoopInfo* TryGetLoopInfoFor(int header_offset) const;
135
136 const ZoneMap<int, LoopInfo>& GetLoopInfos() const { return header_to_info_; }
137
138 // Get the top-level resume jump targets.
140 return resume_jump_targets_;
141 }
142
143 // Gets the in-/out-liveness for the bytecode at {offset}.
144 const BytecodeLivenessState* GetInLivenessFor(int offset) const;
145 const BytecodeLivenessState* GetOutLivenessFor(int offset) const;
146
147 // In the case of OSR, the analysis also computes the (bytecode offset of the)
148 // OSR entry point from the {osr_bailout_id} that was given to the
149 // constructor.
150 int osr_entry_point() const {
151 CHECK_LE(0, osr_entry_point_);
152 return osr_entry_point_;
153 }
154 // Return the osr_bailout_id (for verification purposes).
155 BytecodeOffset osr_bailout_id() const { return osr_bailout_id_; }
156
157 // Return whether liveness analysis was performed (for verification purposes).
158 bool liveness_analyzed() const { return analyze_liveness_; }
159
160 // Return the number of bytecodes (i.e. the number of bytecode operations, as
161 // opposed to the number of bytes in the bytecode).
162 int bytecode_count() const { return bytecode_count_; }
163
164 private:
166 DCHECK(analyze_liveness_);
167 return *liveness_map_;
168 }
170 DCHECK(analyze_liveness_);
171 return *liveness_map_;
172 }
173
180 std::optional<BytecodeLivenessMap> liveness_map_;
181 int bytecode_count_ = -1;
182
185};
186
187} // namespace compiler
188} // namespace internal
189} // namespace v8
190
191#endif // V8_COMPILER_BYTECODE_ANALYSIS_H_
int16_t parameter_count
Definition builtins.cc:67
const BytecodeLivenessMap & liveness_map() const
const ZoneVector< ResumeJumpTarget > & resume_jump_targets() const
std::optional< BytecodeLivenessMap > liveness_map_
const ZoneMap< int, LoopInfo > & GetLoopInfos() const
BytecodeAnalysis & operator=(const BytecodeAnalysis &)=delete
BytecodeAnalysis(const BytecodeAnalysis &)=delete
ZoneVector< ResumeJumpTarget > resume_jump_targets_
int32_t offset
int r
Definition mul-fft.cc:298
#define CHECK_LE(lhs, rhs)
#define DCHECK(condition)
Definition logging.h:482
#define V8_EXPORT_PRIVATE
Definition macros.h:460
const BytecodeLoopAssignments & assignments() const
BytecodeLoopAssignments assignments_
void AddResumeTarget(const ResumeJumpTarget &target)
LoopInfo(int parent_offset, int loop_start, int loop_end, int parameter_count, int register_count, Zone *zone)
ZoneVector< ResumeJumpTarget > resume_jump_targets_
const ZoneVector< ResumeJumpTarget > & resume_jump_targets() const
BytecodeLoopAssignments & assignments()