OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/interpreter/bytecode-register-optimizer.h" | 5 #include "src/interpreter/bytecode-register-optimizer.h" |
6 | 6 |
7 namespace v8 { | 7 namespace v8 { |
8 namespace internal { | 8 namespace internal { |
9 namespace interpreter { | 9 namespace interpreter { |
10 | 10 |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 for (size_t i = 0; i < register_info_table_.size(); ++i) { | 191 for (size_t i = 0; i < register_info_table_.size(); ++i) { |
192 register_info_table_[i] = new (zone) RegisterInfo( | 192 register_info_table_[i] = new (zone) RegisterInfo( |
193 RegisterFromRegisterInfoTableIndex(i), NextEquivalenceId(), true); | 193 RegisterFromRegisterInfoTableIndex(i), NextEquivalenceId(), true); |
194 DCHECK_EQ(register_info_table_[i]->register_value().index(), | 194 DCHECK_EQ(register_info_table_[i]->register_value().index(), |
195 RegisterFromRegisterInfoTableIndex(i).index()); | 195 RegisterFromRegisterInfoTableIndex(i).index()); |
196 } | 196 } |
197 accumulator_info_ = GetRegisterInfo(accumulator_); | 197 accumulator_info_ = GetRegisterInfo(accumulator_); |
198 DCHECK(accumulator_info_->register_value() == accumulator_); | 198 DCHECK(accumulator_info_->register_value() == accumulator_); |
199 } | 199 } |
200 | 200 |
201 void BytecodeRegisterOptimizer::FlushState() { | 201 // override |
202 if (flushed_) { | 202 Handle<BytecodeArray> BytecodeRegisterOptimizer::ToBytecodeArray( |
203 return; | 203 int fixed_register_count, int parameter_count, |
204 } | 204 Handle<FixedArray> handler_table) { |
205 | 205 FlushState(); |
206 // Materialize all live registers. | 206 return next_stage_->ToBytecodeArray(fixed_register_count, parameter_count, |
207 size_t count = register_info_table_.size(); | 207 handler_table); |
208 for (size_t i = 0; i < count; ++i) { | |
209 RegisterInfo* reg_info = register_info_table_[i]; | |
210 if (!reg_info->IsOnlyMemberOfEquivalenceSet() && | |
211 !reg_info->materialized()) { | |
212 DCHECK(RegisterIsTemporary(reg_info->register_value()) || | |
213 reg_info->register_value() == accumulator_); | |
214 Materialize(reg_info); | |
215 } | |
216 } | |
217 | |
218 // Break all existing equivalences. | |
219 for (size_t i = 0; i < count; ++i) { | |
220 RegisterInfo* reg_info = register_info_table_[i]; | |
221 if (!reg_info->IsOnlyMemberOfEquivalenceSet()) { | |
222 reg_info->MoveToNewEquivalenceSet(NextEquivalenceId(), true); | |
223 } | |
224 } | |
225 | |
226 flushed_ = true; | |
227 } | 208 } |
228 | 209 |
229 // override | 210 // override |
230 void BytecodeRegisterOptimizer::FlushBasicBlock() { | |
231 FlushState(); | |
232 next_stage_->FlushBasicBlock(); | |
233 } | |
234 | |
235 // override | |
236 size_t BytecodeRegisterOptimizer::FlushForOffset() { | |
237 FlushState(); | |
238 return next_stage_->FlushForOffset(); | |
239 } | |
240 | |
241 // override | |
242 void BytecodeRegisterOptimizer::Write(BytecodeNode* node) { | 211 void BytecodeRegisterOptimizer::Write(BytecodeNode* node) { |
243 flushed_ = false; | 212 flushed_ = false; |
244 | 213 |
245 // | 214 // |
246 // Transfers with observable registers as the destination will be | 215 // Transfers with observable registers as the destination will be |
247 // immediately materialized so the source position information will | 216 // immediately materialized so the source position information will |
248 // be ordered correctly. | 217 // be ordered correctly. |
249 // | 218 // |
250 // Transfers without observable destination registers will initially | 219 // Transfers without observable destination registers will initially |
251 // be emitted as Nop's with the source position. They may, or may | 220 // be emitted as Nop's with the source position. They may, or may |
(...skipping 24 matching lines...) Expand all Loading... |
276 // everything before handing over to it. Similarly, all state must | 245 // everything before handing over to it. Similarly, all state must |
277 // be flushed before emitting a jump due to how bytecode offsets | 246 // be flushed before emitting a jump due to how bytecode offsets |
278 // for jumps are evaluated. | 247 // for jumps are evaluated. |
279 FlushState(); | 248 FlushState(); |
280 } | 249 } |
281 | 250 |
282 PrepareOperands(node); | 251 PrepareOperands(node); |
283 WriteToNextStage(node); | 252 WriteToNextStage(node); |
284 } | 253 } |
285 | 254 |
| 255 // override |
| 256 void BytecodeRegisterOptimizer::WriteJump(BytecodeNode* node, |
| 257 BytecodeLabel* label) { |
| 258 FlushState(); |
| 259 next_stage_->WriteJump(node, label); |
| 260 } |
| 261 |
| 262 // override |
| 263 void BytecodeRegisterOptimizer::BindLabel(BytecodeLabel* label) { |
| 264 FlushState(); |
| 265 next_stage_->BindLabel(label); |
| 266 } |
| 267 |
| 268 // override |
| 269 void BytecodeRegisterOptimizer::BindLabel(const BytecodeLabel& target, |
| 270 BytecodeLabel* label) { |
| 271 // There is no need to flush here, it will have been flushed when |target| |
| 272 // was bound. |
| 273 next_stage_->BindLabel(target, label); |
| 274 } |
| 275 |
| 276 void BytecodeRegisterOptimizer::FlushState() { |
| 277 if (flushed_) { |
| 278 return; |
| 279 } |
| 280 |
| 281 // Materialize all live registers. |
| 282 size_t count = register_info_table_.size(); |
| 283 for (size_t i = 0; i < count; ++i) { |
| 284 RegisterInfo* reg_info = register_info_table_[i]; |
| 285 if (!reg_info->IsOnlyMemberOfEquivalenceSet() && |
| 286 !reg_info->materialized()) { |
| 287 DCHECK(RegisterIsTemporary(reg_info->register_value()) || |
| 288 reg_info->register_value() == accumulator_); |
| 289 Materialize(reg_info); |
| 290 } |
| 291 } |
| 292 |
| 293 // Break all existing equivalences. |
| 294 for (size_t i = 0; i < count; ++i) { |
| 295 RegisterInfo* reg_info = register_info_table_[i]; |
| 296 if (!reg_info->IsOnlyMemberOfEquivalenceSet()) { |
| 297 reg_info->MoveToNewEquivalenceSet(NextEquivalenceId(), true); |
| 298 } |
| 299 } |
| 300 |
| 301 flushed_ = true; |
| 302 } |
| 303 |
286 void BytecodeRegisterOptimizer::WriteToNextStage(BytecodeNode* node) const { | 304 void BytecodeRegisterOptimizer::WriteToNextStage(BytecodeNode* node) const { |
287 next_stage_->Write(node); | 305 next_stage_->Write(node); |
288 } | 306 } |
289 | 307 |
290 void BytecodeRegisterOptimizer::WriteToNextStage( | 308 void BytecodeRegisterOptimizer::WriteToNextStage( |
291 BytecodeNode* node, const BytecodeSourceInfo& source_info) const { | 309 BytecodeNode* node, const BytecodeSourceInfo& source_info) const { |
292 node->source_info().Update(source_info); | 310 node->source_info().Update(source_info); |
293 next_stage_->Write(node); | 311 next_stage_->Write(node); |
294 } | 312 } |
295 | 313 |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 if (info->materialized()) { | 615 if (info->materialized()) { |
598 CreateMaterializedEquivalent(info); | 616 CreateMaterializedEquivalent(info); |
599 } | 617 } |
600 info->MoveToNewEquivalenceSet(kInvalidEquivalenceId, false); | 618 info->MoveToNewEquivalenceSet(kInvalidEquivalenceId, false); |
601 } | 619 } |
602 } | 620 } |
603 | 621 |
604 } // namespace interpreter | 622 } // namespace interpreter |
605 } // namespace internal | 623 } // namespace internal |
606 } // namespace v8 | 624 } // namespace v8 |
OLD | NEW |