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

Side by Side Diff: src/interpreter/bytecode-register-optimizer.cc

Issue 2369873002: [Interpreter] Replace BytecodeRegisterAllocator with a simple bump pointer. (Closed)
Patch Set: Add dcheck Created 4 years, 2 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
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
11 const uint32_t BytecodeRegisterOptimizer::kInvalidEquivalenceId; 11 const uint32_t BytecodeRegisterOptimizer::kInvalidEquivalenceId;
12 12
13 // A class for tracking the state of a register. This class tracks 13 // A class for tracking the state of a register. This class tracks
14 // which equivalence set a register is a member of and also whether a 14 // which equivalence set a register is a member of and also whether a
15 // register is materialized in the bytecode stream. 15 // register is materialized in the bytecode stream.
16 class BytecodeRegisterOptimizer::RegisterInfo final : public ZoneObject { 16 class BytecodeRegisterOptimizer::RegisterInfo final : public ZoneObject {
17 public: 17 public:
18 RegisterInfo(Register reg, uint32_t equivalence_id, bool materialized) 18 RegisterInfo(Register reg, uint32_t equivalence_id, bool materialized,
19 bool allocated)
19 : register_(reg), 20 : register_(reg),
20 equivalence_id_(equivalence_id), 21 equivalence_id_(equivalence_id),
21 materialized_(materialized), 22 materialized_(materialized),
23 allocated_(allocated),
22 next_(this), 24 next_(this),
23 prev_(this) {} 25 prev_(this) {}
24 26
25 void AddToEquivalenceSetOf(RegisterInfo* info); 27 void AddToEquivalenceSetOf(RegisterInfo* info);
26 void MoveToNewEquivalenceSet(uint32_t equivalence_id, bool materialized); 28 void MoveToNewEquivalenceSet(uint32_t equivalence_id, bool materialized);
27 bool IsOnlyMemberOfEquivalenceSet() const; 29 bool IsOnlyMemberOfEquivalenceSet() const;
28 bool IsOnlyMaterializedMemberOfEquivalenceSet() const; 30 bool IsOnlyMaterializedMemberOfEquivalenceSet() const;
29 bool IsInSameEquivalenceSet(RegisterInfo* info) const; 31 bool IsInSameEquivalenceSet(RegisterInfo* info) const;
30 32
31 // Get a member of this register's equivalence set that is 33 // Get a member of this register's equivalence set that is
32 // materialized. The materialized equivalent will be this register 34 // materialized. The materialized equivalent will be this register
33 // if it is materialized. Returns nullptr if no materialized 35 // if it is materialized. Returns nullptr if no materialized
34 // equivalent exists. 36 // equivalent exists.
35 RegisterInfo* GetMaterializedEquivalent(); 37 RegisterInfo* GetMaterializedEquivalent();
36 38
37 // Get a member of this register's equivalence set that is 39 // Get a member of this register's equivalence set that is
38 // materialized and not register |reg|. The materialized equivalent 40 // materialized and not register |reg|. The materialized equivalent
39 // will be this register if it is materialized. Returns nullptr if 41 // will be this register if it is materialized. Returns nullptr if
40 // no materialized equivalent exists. 42 // no materialized equivalent exists.
41 RegisterInfo* GetMaterializedEquivalentOtherThan(Register reg); 43 RegisterInfo* GetMaterializedEquivalentOtherThan(Register reg);
42 44
43 // Get a member of this register's equivalence set that is intended 45 // Get a member of this register's equivalence set that is intended
44 // to be materialized in place of this register (which is currently 46 // to be materialized in place of this register (which is currently
45 // materialized). The best candidate is deemed to be the register 47 // materialized). The best candidate is deemed to be the register
46 // with the lowest index as this permits temporary registers to be 48 // with the lowest index as this permits temporary registers to be
47 // removed from the bytecode stream. Returns nullptr if no candidate 49 // removed from the bytecode stream. Returns nullptr if no candidate
48 // exists. 50 // exists.
49 RegisterInfo* GetEquivalentToMaterialize(); 51 RegisterInfo* GetEquivalentToMaterialize();
50 52
53 // Marks all temporary registers of the equivalence set as unmaterialized.
54 void MarkTemporariesAsUnmaterialized(Register temporary_base);
55
51 // Get an equivalent register. Returns this if none exists. 56 // Get an equivalent register. Returns this if none exists.
52 RegisterInfo* GetEquivalent(); 57 RegisterInfo* GetEquivalent();
53 58
54 Register register_value() const { return register_; } 59 Register register_value() const { return register_; }
55 bool materialized() const { return materialized_; } 60 bool materialized() const { return materialized_; }
56 void set_materialized(bool materialized) { materialized_ = materialized; } 61 void set_materialized(bool materialized) { materialized_ = materialized; }
62 bool allocated() const { return allocated_; }
63 void set_allocated(bool allocated) { allocated_ = allocated; }
57 void set_equivalence_id(uint32_t equivalence_id) { 64 void set_equivalence_id(uint32_t equivalence_id) {
58 equivalence_id_ = equivalence_id; 65 equivalence_id_ = equivalence_id;
59 } 66 }
60 uint32_t equivalence_id() const { return equivalence_id_; } 67 uint32_t equivalence_id() const { return equivalence_id_; }
61 68
62 private: 69 private:
63 Register register_; 70 Register register_;
64 uint32_t equivalence_id_; 71 uint32_t equivalence_id_;
65 bool materialized_; 72 bool materialized_;
73 bool allocated_;
66 74
67 // Equivalence set pointers. 75 // Equivalence set pointers.
68 RegisterInfo* next_; 76 RegisterInfo* next_;
69 RegisterInfo* prev_; 77 RegisterInfo* prev_;
70 78
71 DISALLOW_COPY_AND_ASSIGN(RegisterInfo); 79 DISALLOW_COPY_AND_ASSIGN(RegisterInfo);
72 }; 80 };
73 81
74 void BytecodeRegisterOptimizer::RegisterInfo::AddToEquivalenceSetOf( 82 void BytecodeRegisterOptimizer::RegisterInfo::AddToEquivalenceSetOf(
75 RegisterInfo* info) { 83 RegisterInfo* info) {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 153
146 return nullptr; 154 return nullptr;
147 } 155 }
148 156
149 BytecodeRegisterOptimizer::RegisterInfo* 157 BytecodeRegisterOptimizer::RegisterInfo*
150 BytecodeRegisterOptimizer::RegisterInfo::GetEquivalentToMaterialize() { 158 BytecodeRegisterOptimizer::RegisterInfo::GetEquivalentToMaterialize() {
151 DCHECK(this->materialized()); 159 DCHECK(this->materialized());
152 RegisterInfo* visitor = this->next_; 160 RegisterInfo* visitor = this->next_;
153 RegisterInfo* best_info = nullptr; 161 RegisterInfo* best_info = nullptr;
154 while (visitor != this) { 162 while (visitor != this) {
155 if (visitor->materialized()) { 163 if (visitor->materialized()) {
mythria 2016/09/28 11:45:29 I am not sure I understand it fully, but what woul
rmcilroy 2016/09/30 08:37:54 As discussed offline, yes we can reuse it even if
156 return nullptr; 164 return nullptr;
157 } 165 }
158 if (best_info == nullptr || 166 if (visitor->allocated() &&
159 visitor->register_value() < best_info->register_value()) { 167 (best_info == nullptr ||
168 visitor->register_value() < best_info->register_value())) {
160 best_info = visitor; 169 best_info = visitor;
161 } 170 }
162 visitor = visitor->next_; 171 visitor = visitor->next_;
163 } 172 }
164 return best_info; 173 return best_info;
165 } 174 }
166 175
176 void BytecodeRegisterOptimizer::RegisterInfo::MarkTemporariesAsUnmaterialized(
177 Register temporary_base) {
178 DCHECK(this->register_value() < temporary_base);
179 DCHECK(this->materialized());
180 RegisterInfo* visitor = this->next_;
181 while (visitor != this) {
182 if (visitor->register_value() >= temporary_base) {
183 visitor->set_materialized(false);
184 }
185 visitor = visitor->next_;
186 }
187 }
188
167 BytecodeRegisterOptimizer::RegisterInfo* 189 BytecodeRegisterOptimizer::RegisterInfo*
168 BytecodeRegisterOptimizer::RegisterInfo::GetEquivalent() { 190 BytecodeRegisterOptimizer::RegisterInfo::GetEquivalent() {
169 return next_; 191 return next_;
170 } 192 }
171 193
172 BytecodeRegisterOptimizer::BytecodeRegisterOptimizer( 194 BytecodeRegisterOptimizer::BytecodeRegisterOptimizer(
173 Zone* zone, TemporaryRegisterAllocator* register_allocator, 195 Zone* zone, BytecodeRegisterAllocator* register_allocator,
174 int parameter_count, BytecodePipelineStage* next_stage) 196 int fixed_registers_count, int parameter_count,
197 BytecodePipelineStage* next_stage)
175 : accumulator_(Register::virtual_accumulator()), 198 : accumulator_(Register::virtual_accumulator()),
176 temporary_base_(register_allocator->allocation_base()), 199 temporary_base_(fixed_registers_count),
177 max_register_index_(register_allocator->allocation_base() - 1), 200 max_register_index_(fixed_registers_count - 1),
178 register_info_table_(zone), 201 register_info_table_(zone),
179 equivalence_id_(0), 202 equivalence_id_(0),
180 next_stage_(next_stage), 203 next_stage_(next_stage),
181 flush_required_(false), 204 flush_required_(false),
182 zone_(zone) { 205 zone_(zone) {
183 register_allocator->set_observer(this); 206 register_allocator->set_observer(this);
184 207
185 // Calculate offset so register index values can be mapped into 208 // Calculate offset so register index values can be mapped into
186 // a vector of register metadata. 209 // a vector of register metadata.
187 if (parameter_count != 0) { 210 if (parameter_count != 0) {
188 register_info_table_offset_ = 211 register_info_table_offset_ =
189 -Register::FromParameterIndex(0, parameter_count).index(); 212 -Register::FromParameterIndex(0, parameter_count).index();
190 } else { 213 } else {
191 // TODO(oth): This path shouldn't be necessary in bytecode generated 214 // TODO(oth): This path shouldn't be necessary in bytecode generated
192 // from Javascript, but a set of tests do not include the JS receiver. 215 // from Javascript, but a set of tests do not include the JS receiver.
193 register_info_table_offset_ = -accumulator_.index(); 216 register_info_table_offset_ = -accumulator_.index();
194 } 217 }
195 218
196 // Initialize register map for parameters, locals, and the 219 // Initialize register map for parameters, locals, and the
197 // accumulator. 220 // accumulator.
198 register_info_table_.resize(register_info_table_offset_ + 221 register_info_table_.resize(register_info_table_offset_ +
199 static_cast<size_t>(temporary_base_.index())); 222 static_cast<size_t>(temporary_base_.index()));
200 for (size_t i = 0; i < register_info_table_.size(); ++i) { 223 for (size_t i = 0; i < register_info_table_.size(); ++i) {
201 register_info_table_[i] = new (zone) RegisterInfo( 224 register_info_table_[i] = new (zone) RegisterInfo(
202 RegisterFromRegisterInfoTableIndex(i), NextEquivalenceId(), true); 225 RegisterFromRegisterInfoTableIndex(i), NextEquivalenceId(), true, true);
203 DCHECK_EQ(register_info_table_[i]->register_value().index(), 226 DCHECK_EQ(register_info_table_[i]->register_value().index(),
204 RegisterFromRegisterInfoTableIndex(i).index()); 227 RegisterFromRegisterInfoTableIndex(i).index());
205 } 228 }
206 accumulator_info_ = GetRegisterInfo(accumulator_); 229 accumulator_info_ = GetRegisterInfo(accumulator_);
207 DCHECK(accumulator_info_->register_value() == accumulator_); 230 DCHECK(accumulator_info_->register_value() == accumulator_);
208 } 231 }
209 232
210 // override 233 // override
211 Handle<BytecodeArray> BytecodeRegisterOptimizer::ToBytecodeArray( 234 Handle<BytecodeArray> BytecodeRegisterOptimizer::ToBytecodeArray(
212 Isolate* isolate, int register_count, int parameter_count, 235 Isolate* isolate, int register_count, int parameter_count,
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 // Materialize all live registers and break equivalences. 312 // Materialize all live registers and break equivalences.
290 size_t count = register_info_table_.size(); 313 size_t count = register_info_table_.size();
291 for (size_t i = 0; i < count; ++i) { 314 for (size_t i = 0; i < count; ++i) {
292 RegisterInfo* reg_info = register_info_table_[i]; 315 RegisterInfo* reg_info = register_info_table_[i];
293 if (reg_info->materialized()) { 316 if (reg_info->materialized()) {
294 // Walk equivalents of materialized registers, materializing 317 // Walk equivalents of materialized registers, materializing
295 // each equivalent register as necessary and placing in their 318 // each equivalent register as necessary and placing in their
296 // own equivalence set. 319 // own equivalence set.
297 RegisterInfo* equivalent; 320 RegisterInfo* equivalent;
298 while ((equivalent = reg_info->GetEquivalent()) != reg_info) { 321 while ((equivalent = reg_info->GetEquivalent()) != reg_info) {
299 if (!equivalent->materialized()) { 322 if (equivalent->allocated() && !equivalent->materialized()) {
300 OutputRegisterTransfer(reg_info, equivalent); 323 OutputRegisterTransfer(reg_info, equivalent);
301 } 324 }
302 equivalent->MoveToNewEquivalenceSet(NextEquivalenceId(), true); 325 equivalent->MoveToNewEquivalenceSet(NextEquivalenceId(), true);
303 } 326 }
304 } 327 }
305 } 328 }
306 329
307 flush_required_ = false; 330 flush_required_ = false;
308 } 331 }
309 332
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 RegisterIsObservable(output_info->register_value()); 420 RegisterIsObservable(output_info->register_value());
398 if (output_is_observable) { 421 if (output_is_observable) {
399 // Force store to be emitted when register is observable. 422 // Force store to be emitted when register is observable.
400 output_info->set_materialized(false); 423 output_info->set_materialized(false);
401 RegisterInfo* materialized_info = input_info->GetMaterializedEquivalent(); 424 RegisterInfo* materialized_info = input_info->GetMaterializedEquivalent();
402 OutputRegisterTransfer(materialized_info, output_info, source_info); 425 OutputRegisterTransfer(materialized_info, output_info, source_info);
403 } else if (source_info->is_valid()) { 426 } else if (source_info->is_valid()) {
404 // Emit a placeholder nop to maintain source position info. 427 // Emit a placeholder nop to maintain source position info.
405 EmitNopForSourceInfo(source_info); 428 EmitNopForSourceInfo(source_info);
406 } 429 }
430
431 bool input_is_observable = RegisterIsObservable(input_info->register_value());
432 if (input_is_observable) {
433 // If input is observable by the debugger, mark all other temporaries
434 // registers as unmaterialized so that this register is used in preference.
435 input_info->MarkTemporariesAsUnmaterialized(temporary_base_);
436 }
407 } 437 }
408 438
409 void BytecodeRegisterOptimizer::EmitNopForSourceInfo( 439 void BytecodeRegisterOptimizer::EmitNopForSourceInfo(
410 BytecodeSourceInfo* source_info) const { 440 BytecodeSourceInfo* source_info) const {
411 DCHECK(source_info->is_valid()); 441 DCHECK(source_info->is_valid());
412 BytecodeNode nop(Bytecode::kNop, source_info); 442 BytecodeNode nop(Bytecode::kNop, source_info);
413 next_stage_->Write(&nop); 443 next_stage_->Write(&nop);
414 } 444 }
415 445
416 void BytecodeRegisterOptimizer::DoLdar(BytecodeNode* node) { 446 void BytecodeRegisterOptimizer::DoLdar(BytecodeNode* node) {
417 Register input = GetRegisterInputOperand( 447 Register input = GetRegisterInputOperand(
418 0, node->bytecode(), node->operands(), node->operand_count()); 448 0, node->bytecode(), node->operands(), node->operand_count());
419 RegisterInfo* input_info = GetRegisterInfo(input); 449 RegisterInfo* input_info = GetRegisterInfo(input);
420 RegisterTransfer(input_info, accumulator_info_, node->source_info_ptr()); 450 RegisterTransfer(input_info, accumulator_info_, node->source_info_ptr());
421 } 451 }
422 452
423 void BytecodeRegisterOptimizer::DoMov(BytecodeNode* node) { 453 void BytecodeRegisterOptimizer::DoMov(BytecodeNode* node) {
424 Register input = GetRegisterInputOperand( 454 Register input = GetRegisterInputOperand(
425 0, node->bytecode(), node->operands(), node->operand_count()); 455 0, node->bytecode(), node->operands(), node->operand_count());
426 RegisterInfo* input_info = GetRegisterInfo(input); 456 RegisterInfo* input_info = GetRegisterInfo(input);
427 Register output = GetRegisterOutputOperand( 457 Register output = GetRegisterOutputOperand(
428 1, node->bytecode(), node->operands(), node->operand_count()); 458 1, node->bytecode(), node->operands(), node->operand_count());
429 RegisterInfo* output_info = GetOrCreateRegisterInfo(output); 459 RegisterInfo* output_info = GetRegisterInfo(output);
430 RegisterTransfer(input_info, output_info, node->source_info_ptr()); 460 RegisterTransfer(input_info, output_info, node->source_info_ptr());
431 } 461 }
432 462
433 void BytecodeRegisterOptimizer::DoStar(BytecodeNode* node) { 463 void BytecodeRegisterOptimizer::DoStar(BytecodeNode* node) {
434 Register output = GetRegisterOutputOperand( 464 Register output = GetRegisterOutputOperand(
435 0, node->bytecode(), node->operands(), node->operand_count()); 465 0, node->bytecode(), node->operands(), node->operand_count());
436 RegisterInfo* output_info = GetOrCreateRegisterInfo(output); 466 RegisterInfo* output_info = GetRegisterInfo(output);
437 RegisterTransfer(accumulator_info_, output_info, node->source_info_ptr()); 467 RegisterTransfer(accumulator_info_, output_info, node->source_info_ptr());
438 } 468 }
439 469
440 void BytecodeRegisterOptimizer::PrepareRegisterOutputOperand( 470 void BytecodeRegisterOptimizer::PrepareRegisterOutputOperand(
441 RegisterInfo* reg_info) { 471 RegisterInfo* reg_info) {
442 if (reg_info->materialized()) { 472 if (reg_info->materialized()) {
443 CreateMaterializedEquivalent(reg_info); 473 CreateMaterializedEquivalent(reg_info);
444 } 474 }
445 max_register_index_ = 475 max_register_index_ =
446 std::max(max_register_index_, reg_info->register_value().index()); 476 std::max(max_register_index_, reg_info->register_value().index());
447 reg_info->MoveToNewEquivalenceSet(NextEquivalenceId(), true); 477 reg_info->MoveToNewEquivalenceSet(NextEquivalenceId(), true);
448 } 478 }
449 479
450 void BytecodeRegisterOptimizer::PrepareRegisterRangeOutputOperand( 480 void BytecodeRegisterOptimizer::PrepareRegisterRangeOutputOperand(
451 Register start, int count) { 481 Register start, int count) {
452 for (int i = 0; i < count; ++i) { 482 for (int i = 0; i < count; ++i) {
453 Register reg(start.index() + i); 483 Register reg(start.index() + i);
454 RegisterInfo* reg_info = GetOrCreateRegisterInfo(reg); 484 RegisterInfo* reg_info = GetRegisterInfo(reg);
455 PrepareRegisterOutputOperand(reg_info); 485 PrepareRegisterOutputOperand(reg_info);
456 } 486 }
457 } 487 }
458 488
459 Register BytecodeRegisterOptimizer::GetEquivalentRegisterForInputOperand( 489 Register BytecodeRegisterOptimizer::GetEquivalentRegisterForInputOperand(
460 Register reg) { 490 Register reg) {
461 // For a temporary register, RegInfo state may need be created. For 491 // For a temporary register, RegInfo state may need be created. For
462 // locals and parameters, the RegInfo state is created in the 492 // locals and parameters, the RegInfo state is created in the
463 // BytecodeRegisterOptimizer constructor. 493 // BytecodeRegisterOptimizer constructor.
464 RegisterInfo* reg_info = GetOrCreateRegisterInfo(reg); 494 RegisterInfo* reg_info = GetRegisterInfo(reg);
465 if (reg_info->materialized()) { 495 if (reg_info->materialized()) {
466 return reg; 496 return reg;
467 } else { 497 } else {
468 RegisterInfo* equivalent_info = 498 RegisterInfo* equivalent_info =
469 GetMaterializedEquivalentNotAccumulator(reg_info); 499 GetMaterializedEquivalentNotAccumulator(reg_info);
470 return equivalent_info->register_value(); 500 return equivalent_info->register_value();
471 } 501 }
472 } 502 }
473 503
474 void BytecodeRegisterOptimizer::PrepareRegisterInputOperand( 504 void BytecodeRegisterOptimizer::PrepareRegisterInputOperand(
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 int index, Bytecode bytecode, const uint32_t* operands, int operand_count) { 593 int index, Bytecode bytecode, const uint32_t* operands, int operand_count) {
564 DCHECK_LT(index, operand_count); 594 DCHECK_LT(index, operand_count);
565 DCHECK(Bytecodes::IsRegisterOutputOperandType( 595 DCHECK(Bytecodes::IsRegisterOutputOperandType(
566 Bytecodes::GetOperandType(bytecode, index))); 596 Bytecodes::GetOperandType(bytecode, index)));
567 return OperandToRegister(operands[index]); 597 return OperandToRegister(operands[index]);
568 } 598 }
569 599
570 BytecodeRegisterOptimizer::RegisterInfo* 600 BytecodeRegisterOptimizer::RegisterInfo*
571 BytecodeRegisterOptimizer::GetRegisterInfo(Register reg) { 601 BytecodeRegisterOptimizer::GetRegisterInfo(Register reg) {
572 size_t index = GetRegisterInfoTableIndex(reg); 602 size_t index = GetRegisterInfoTableIndex(reg);
573 return (index < register_info_table_.size()) ? register_info_table_[index] 603 DCHECK_LT(index, register_info_table_.size());
574 : nullptr; 604 return register_info_table_[index];
575 } 605 }
576 606
577 BytecodeRegisterOptimizer::RegisterInfo* 607 BytecodeRegisterOptimizer::RegisterInfo*
578 BytecodeRegisterOptimizer::GetOrCreateRegisterInfo(Register reg) { 608 BytecodeRegisterOptimizer::GetOrCreateRegisterInfo(Register reg) {
579 size_t index = GetRegisterInfoTableIndex(reg); 609 size_t index = GetRegisterInfoTableIndex(reg);
580 return index < register_info_table_.size() ? register_info_table_[index] 610 return index < register_info_table_.size() ? register_info_table_[index]
581 : NewRegisterInfo(reg); 611 : NewRegisterInfo(reg);
582 } 612 }
583 613
584 BytecodeRegisterOptimizer::RegisterInfo* 614 BytecodeRegisterOptimizer::RegisterInfo*
585 BytecodeRegisterOptimizer::NewRegisterInfo(Register reg) { 615 BytecodeRegisterOptimizer::NewRegisterInfo(Register reg) {
586 size_t index = GetRegisterInfoTableIndex(reg); 616 size_t index = GetRegisterInfoTableIndex(reg);
587 DCHECK_GE(index, register_info_table_.size()); 617 DCHECK_GE(index, register_info_table_.size());
588 GrowRegisterMap(reg); 618 GrowRegisterMap(reg);
589 return register_info_table_[index]; 619 return register_info_table_[index];
590 } 620 }
591 621
592 void BytecodeRegisterOptimizer::GrowRegisterMap(Register reg) { 622 void BytecodeRegisterOptimizer::GrowRegisterMap(Register reg) {
593 DCHECK(RegisterIsTemporary(reg)); 623 DCHECK(RegisterIsTemporary(reg));
594 size_t index = GetRegisterInfoTableIndex(reg); 624 size_t index = GetRegisterInfoTableIndex(reg);
595 DCHECK_GE(index, register_info_table_.size()); 625 if (index >= register_info_table_.size()) {
596 size_t new_size = index + 1; 626 size_t new_size = index + 1;
597 size_t old_size = register_info_table_.size(); 627 size_t old_size = register_info_table_.size();
598 register_info_table_.resize(new_size); 628 register_info_table_.resize(new_size);
599 for (size_t i = old_size; i < new_size; ++i) { 629 for (size_t i = old_size; i < new_size; ++i) {
600 register_info_table_[i] = new (zone()) RegisterInfo( 630 register_info_table_[i] =
601 RegisterFromRegisterInfoTableIndex(i), NextEquivalenceId(), false); 631 new (zone()) RegisterInfo(RegisterFromRegisterInfoTableIndex(i),
632 NextEquivalenceId(), false, false);
633 }
602 } 634 }
603 } 635 }
604 636
605 void BytecodeRegisterOptimizer::TemporaryRegisterFreeEvent(Register reg) { 637 void BytecodeRegisterOptimizer::RegisterAllocateEvent(Register reg) {
606 RegisterInfo* info = GetRegisterInfo(reg); 638 GetOrCreateRegisterInfo(reg)->set_allocated(true);
607 if (info != nullptr) { 639 }
608 // If register is materialized and part of equivalence set, make 640
609 // sure another member of the set holds the value before the 641 void BytecodeRegisterOptimizer::RegisterListAllocateEvent(
610 // temporary register is removed. 642 RegisterList reg_list) {
611 if (info->materialized()) { 643 if (reg_list.register_count() != 0) {
612 CreateMaterializedEquivalent(info); 644 int first_index = reg_list.first_register().index();
645 GrowRegisterMap(Register(first_index + reg_list.register_count() - 1));
646 for (int i = 0; i < reg_list.register_count(); i++) {
647 GetRegisterInfo(Register(first_index + i))->set_allocated(true);
613 } 648 }
614 info->MoveToNewEquivalenceSet(kInvalidEquivalenceId, false);
615 } 649 }
616 } 650 }
617 651
652 void BytecodeRegisterOptimizer::RegisterListFreeEvent(RegisterList reg_list) {
653 int first_index = reg_list.first_register().index();
654 for (int i = 0; i < reg_list.register_count(); i++) {
655 GetRegisterInfo(Register(first_index + i))->set_allocated(false);
656 }
mythria 2016/09/28 11:45:29 If I understand correctly, the idea here is that,
rmcilroy 2016/09/30 08:37:54 As discussed offline, we don't need to materialize
657 }
658
618 } // namespace interpreter 659 } // namespace interpreter
619 } // namespace internal 660 } // namespace internal
620 } // namespace v8 661 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698