Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(703)

Side by Side Diff: src/interpreter/bytecode-writer.cc

Issue 1947403002: [interpreter] Introduce bytecode generation pipeline. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Attempt to fix compilation with gcc/msvc and introduce nop to simplify source positions in peephole… Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 #include "src/interpreter/bytecode-writer.h"
6
7 #include <iomanip>
8 #include "src/interpreter/source-position-table.h"
9
10 namespace v8 {
11 namespace internal {
12 namespace interpreter {
13
14 void BytecodeSourceInfo::Update(const BytecodeSourceInfo& entry) {
15 DCHECK(entry.is_valid());
16 if (!is_valid() || (entry.is_statement() && !is_statement()) ||
17 (entry.is_statement() && is_statement() &&
18 entry.source_position() > source_position())) {
19 // Position is updated if there is no existing position. Or the
20 // incoming position is a statement and the current position is an
21 // expression. Or we already have a statement and incoming
22 // statement is later. This last piece is needed for the first
23 // statement in a function.
24 source_position_ = entry.source_position_;
25 is_statement_ = entry.is_statement_;
26 }
27 }
28
29 BytecodeNode::BytecodeNode(BytecodeNodeAllocator* allocator)
30 : bytecode_(Bytecode::kIllegal),
31 operand_scale_(OperandScale::kSingle),
32 allocator_(allocator) {}
33
34 void BytecodeNode::set_bytecode(Bytecode bytecode) {
35 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0);
36 bytecode_ = bytecode;
37 operand_scale_ = OperandScale::kSingle;
38 }
39
40 void BytecodeNode::set_bytecode(Bytecode bytecode, uint32_t operand0,
41 OperandScale operand_scale) {
42 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 1);
43 bytecode_ = bytecode;
44 operands_[0] = operand0;
45 operand_scale_ = operand_scale;
46 }
47
48 void BytecodeNode::set_bytecode(Bytecode bytecode, uint32_t operand0,
49 uint32_t operand1, OperandScale operand_scale) {
50 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 2);
51 bytecode_ = bytecode;
52 operands_[0] = operand0;
53 operands_[1] = operand1;
54 operand_scale_ = operand_scale;
55 }
56
57 void BytecodeNode::set_bytecode(Bytecode bytecode, uint32_t operand0,
58 uint32_t operand1, uint32_t operand2,
59 OperandScale operand_scale) {
60 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 3);
61 bytecode_ = bytecode;
62 operands_[0] = operand0;
63 operands_[1] = operand1;
64 operands_[2] = operand2;
65 operand_scale_ = operand_scale;
66 }
67
68 void BytecodeNode::set_bytecode(Bytecode bytecode, uint32_t operand0,
69 uint32_t operand1, uint32_t operand2,
70 uint32_t operand3, OperandScale operand_scale) {
71 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 4);
72 bytecode_ = bytecode;
73 operands_[0] = operand0;
74 operands_[1] = operand1;
75 operands_[2] = operand2;
76 operands_[3] = operand3;
77 operand_scale_ = operand_scale;
78 }
79
80 size_t BytecodeNode::Size() const {
81 size_t size = Bytecodes::Size(bytecode_, operand_scale_);
82 if (Bytecodes::OperandScaleRequiresPrefixBytecode(operand_scale_)) {
83 size += 1;
84 }
85 return size;
86 }
87
88 void BytecodeNode::Release() {
89 bytecode_ = Bytecode::kIllegal;
90 source_info_.set_invalid();
91 allocator_->Release(this);
92 }
93
94 void BytecodeNode::Print(std::ostream& os) {
95 #ifdef DEBUG
96 std::ios saved_state(nullptr);
97 saved_state.copyfmt(os);
98
99 os << Bytecodes::ToString(bytecode_);
100 if (Bytecodes::OperandScaleRequiresPrefixBytecode(operand_scale_)) {
101 Bytecode scale_prefix =
102 Bytecodes::OperandScaleToPrefixBytecode(operand_scale_);
103 os << '.' << Bytecodes::ToString(scale_prefix);
104 }
105
106 for (int i = 0; i < operand_count(); ++i) {
107 os << ' ' << std::setw(8) << std::setfill('0') << std::hex << operands_[i];
108 }
109 os.copyfmt(saved_state);
110
111 if (source_info_.is_valid()) {
112 char type = source_info_.is_statement() ? 'S' : 'E';
113 os << ' ' << type << '@' << source_info_.source_position();
114 }
115 os << '\n';
116 #endif // DEBUG
117 }
118
119 BytecodeNode* BytecodeNodeAllocator::Allocate() {
120 if (free_list_ != nullptr) {
121 BytecodeNode* node = free_list_;
122 free_list_ = free_list_->next_;
123 return node;
124 } else {
125 DCHECK_LT(allocation_count_, kMaxDebugAllocations);
126 allocation_count_++;
127 return new (zone()) BytecodeNode(this);
128 }
129 }
130
131 void BytecodeNodeAllocator::Release(BytecodeNode* node) {
132 node->next_ = free_list_;
133 free_list_ = node;
134 }
135
136 FinalStageBytecodeWriter::FinalStageBytecodeWriter(
137 Zone* zone, SourcePositionTableBuilder* source_position_table_builder)
138 : bytecodes_(zone),
139 frame_register_count_(0),
140 source_position_table_builder_(source_position_table_builder) {
141 bytecodes_.reserve(256);
142 }
143
144 // override
145 FinalStageBytecodeWriter::~FinalStageBytecodeWriter() {}
146
147 // override
148 size_t FinalStageBytecodeWriter::FlushForOffset() {
149 return bytecodes()->size();
150 }
151
152 // override
153 void FinalStageBytecodeWriter::Write(BytecodeNode* node) {
154 UpdateSourcePositionTable(node);
155 EmitBytecode(node);
156 node->Release();
157 }
158
159 void FinalStageBytecodeWriter::UpdateSourcePositionTable(
160 const BytecodeNode* const node) {
161 int bytecode_offset = static_cast<int>(bytecodes()->size());
162 const BytecodeSourceInfo& source_info = node->source_info();
163 if (source_info.is_valid()) {
164 if (source_info.is_statement()) {
165 source_position_table_builder_->AddStatementPosition(
166 bytecode_offset, source_info.source_position());
167 } else {
168 source_position_table_builder_->AddExpressionPosition(
169 bytecode_offset, source_info.source_position());
170 }
171 }
172 }
173
174 void FinalStageBytecodeWriter::EmitBytecode(const BytecodeNode* const node) {
175 OperandScale operand_scale = node->operand_scale();
176 if (operand_scale != OperandScale::kSingle) {
177 Bytecode prefix = Bytecodes::OperandScaleToPrefixBytecode(operand_scale);
178 bytecodes()->push_back(Bytecodes::ToByte(prefix));
179 }
180
181 Bytecode bytecode = node->bytecode();
182 bytecodes()->push_back(Bytecodes::ToByte(bytecode));
183
184 int register_operand_bitmap = Bytecodes::GetRegisterOperandBitmap(bytecode);
185 const uint32_t* const operands = node->operands();
186 const OperandType* operand_types = Bytecodes::GetOperandTypes(bytecode);
187 for (int i = 0; operand_types[i] != OperandType::kNone; ++i) {
188 OperandType operand_type = operand_types[i];
189 switch (Bytecodes::SizeOfOperand(operand_type, operand_scale)) {
190 case OperandSize::kNone:
191 UNREACHABLE();
192 break;
193 case OperandSize::kByte:
194 bytecodes()->push_back(static_cast<uint8_t>(operands[i]));
195 break;
196 case OperandSize::kShort: {
197 uint8_t operand_bytes[2];
198 WriteUnalignedUInt16(operand_bytes, operands[i]);
199 bytecodes()->insert(bytecodes()->end(), operand_bytes,
200 operand_bytes + 2);
201 break;
202 }
203 case OperandSize::kQuad: {
204 uint8_t operand_bytes[4];
205 WriteUnalignedUInt32(operand_bytes, operands[i]);
206 bytecodes()->insert(bytecodes()->end(), operand_bytes,
207 operand_bytes + 4);
208 break;
209 }
210 }
211
212 if ((register_operand_bitmap >> i) & 1) {
213 int count;
214 if (operand_types[i + 1] == OperandType::kRegCount) {
215 count = static_cast<int>(operands[i + 1]);
216 } else {
217 count = Bytecodes::GetNumberOfRegistersRepresentedBy(operand_type);
218 }
219 Register reg = Register::FromOperand(static_cast<int32_t>(operands[i]));
220 frame_register_count_ =
221 std::max(frame_register_count_, reg.index() + count);
222 }
223 }
224 }
225
226 // override
227 void FinalStageBytecodeWriter::LeaveBasicBlock() {}
228
229 int FinalStageBytecodeWriter::GetMeasuredFrameSize() {
230 return frame_register_count_ * kPointerSize;
231 }
232
233 } // namespace interpreter
234 } // namespace internal
235 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698