| 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 |