OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 #ifndef V8_REGISTER_ALLOCATOR_H_ | 5 #ifndef V8_REGISTER_ALLOCATOR_H_ |
6 #define V8_REGISTER_ALLOCATOR_H_ | 6 #define V8_REGISTER_ALLOCATOR_H_ |
7 | 7 |
8 #include "src/compiler/instruction.h" | 8 #include "src/compiler/instruction.h" |
9 #include "src/zone-containers.h" | 9 #include "src/zone-containers.h" |
10 | 10 |
11 namespace v8 { | 11 namespace v8 { |
12 namespace internal { | 12 namespace internal { |
13 namespace compiler { | 13 namespace compiler { |
14 | 14 |
15 enum RegisterKind { | 15 enum RegisterKind { |
16 UNALLOCATED_REGISTERS, | |
17 GENERAL_REGISTERS, | 16 GENERAL_REGISTERS, |
18 DOUBLE_REGISTERS | 17 DOUBLE_REGISTERS |
19 }; | 18 }; |
20 | 19 |
21 | 20 |
22 // This class represents a single point of a InstructionOperand's lifetime. For | 21 // This class represents a single point of a InstructionOperand's lifetime. For |
23 // each instruction there are four lifetime positions: | 22 // each instruction there are four lifetime positions: |
24 // | 23 // |
25 // [[START, END], [START, END]] | 24 // [[START, END], [START, END]] |
26 // | 25 // |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 }; | 264 }; |
266 | 265 |
267 | 266 |
268 class SpillRange; | 267 class SpillRange; |
269 | 268 |
270 | 269 |
271 // Representation of SSA values' live ranges as a collection of (continuous) | 270 // Representation of SSA values' live ranges as a collection of (continuous) |
272 // intervals over the instruction ordering. | 271 // intervals over the instruction ordering. |
273 class LiveRange final : public ZoneObject { | 272 class LiveRange final : public ZoneObject { |
274 public: | 273 public: |
275 explicit LiveRange(int id); | 274 explicit LiveRange(int id, MachineType machine_type); |
276 | 275 |
277 UseInterval* first_interval() const { return first_interval_; } | 276 UseInterval* first_interval() const { return first_interval_; } |
278 UsePosition* first_pos() const { return first_pos_; } | 277 UsePosition* first_pos() const { return first_pos_; } |
279 LiveRange* parent() const { return parent_; } | 278 LiveRange* parent() const { return parent_; } |
280 LiveRange* TopLevel() { return (parent_ == nullptr) ? this : parent_; } | 279 LiveRange* TopLevel() { return (parent_ == nullptr) ? this : parent_; } |
281 const LiveRange* TopLevel() const { | 280 const LiveRange* TopLevel() const { |
282 return (parent_ == nullptr) ? this : parent_; | 281 return (parent_ == nullptr) ? this : parent_; |
283 } | 282 } |
284 LiveRange* next() const { return next_; } | 283 LiveRange* next() const { return next_; } |
285 bool IsChild() const { return parent() != nullptr; } | 284 bool IsChild() const { return parent() != nullptr; } |
286 int id() const { return id_; } | 285 int id() const { return id_; } |
287 bool IsFixed() const { return id_ < 0; } | 286 bool IsFixed() const { return id_ < 0; } |
288 bool IsEmpty() const { return first_interval() == nullptr; } | 287 bool IsEmpty() const { return first_interval() == nullptr; } |
289 InstructionOperand GetAssignedOperand() const; | 288 InstructionOperand GetAssignedOperand() const; |
290 int spill_start_index() const { return spill_start_index_; } | 289 int spill_start_index() const { return spill_start_index_; } |
291 | 290 |
| 291 MachineType machine_type() const { return MachineTypeField::decode(bits_); } |
| 292 |
292 int assigned_register() const { return AssignedRegisterField::decode(bits_); } | 293 int assigned_register() const { return AssignedRegisterField::decode(bits_); } |
293 bool HasRegisterAssigned() const { | 294 bool HasRegisterAssigned() const { |
294 return assigned_register() != kUnassignedRegister; | 295 return assigned_register() != kUnassignedRegister; |
295 } | 296 } |
296 void set_assigned_register(int reg); | 297 void set_assigned_register(int reg); |
297 void UnsetAssignedRegister(); | 298 void UnsetAssignedRegister(); |
298 | 299 |
299 bool spilled() const { return SpilledField::decode(bits_); } | 300 bool spilled() const { return SpilledField::decode(bits_); } |
300 void Spill(); | 301 void Spill(); |
301 | 302 |
302 RegisterKind kind() const { return RegisterKindField::decode(bits_); } | 303 RegisterKind kind() const; |
303 void set_kind(RegisterKind kind) { | |
304 bits_ = RegisterKindField::update(bits_, kind); | |
305 } | |
306 | 304 |
307 // Correct only for parent. | 305 // Correct only for parent. |
308 bool is_phi() const { return IsPhiField::decode(bits_); } | 306 bool is_phi() const { return IsPhiField::decode(bits_); } |
309 void set_is_phi(bool value) { bits_ = IsPhiField::update(bits_, value); } | 307 void set_is_phi(bool value) { bits_ = IsPhiField::update(bits_, value); } |
310 | 308 |
311 // Correct only for parent. | 309 // Correct only for parent. |
312 bool is_non_loop_phi() const { return IsNonLoopPhiField::decode(bits_); } | 310 bool is_non_loop_phi() const { return IsNonLoopPhiField::decode(bits_); } |
313 void set_is_non_loop_phi(bool value) { | 311 void set_is_non_loop_phi(bool value) { |
314 bits_ = IsNonLoopPhiField::update(bits_, value); | 312 bits_ = IsNonLoopPhiField::update(bits_, value); |
315 } | 313 } |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 DCHECK(spill_type() == SpillType::kSpillRange); | 377 DCHECK(spill_type() == SpillType::kSpillRange); |
380 return spill_range_; | 378 return spill_range_; |
381 } | 379 } |
382 bool HasNoSpillType() const { | 380 bool HasNoSpillType() const { |
383 return spill_type() == SpillType::kNoSpillType; | 381 return spill_type() == SpillType::kNoSpillType; |
384 } | 382 } |
385 bool HasSpillOperand() const { | 383 bool HasSpillOperand() const { |
386 return spill_type() == SpillType::kSpillOperand; | 384 return spill_type() == SpillType::kSpillOperand; |
387 } | 385 } |
388 bool HasSpillRange() const { return spill_type() == SpillType::kSpillRange; } | 386 bool HasSpillRange() const { return spill_type() == SpillType::kSpillRange; } |
| 387 AllocatedOperand GetSpillRangeOperand() const; |
389 | 388 |
390 void SpillAtDefinition(Zone* zone, int gap_index, | 389 void SpillAtDefinition(Zone* zone, int gap_index, |
391 InstructionOperand* operand); | 390 InstructionOperand* operand); |
392 void SetSpillOperand(InstructionOperand* operand); | 391 void SetSpillOperand(InstructionOperand* operand); |
393 void SetSpillRange(SpillRange* spill_range); | 392 void SetSpillRange(SpillRange* spill_range); |
394 void CommitSpillOperand(AllocatedOperand* operand); | |
395 void CommitSpillsAtDefinition(InstructionSequence* sequence, | 393 void CommitSpillsAtDefinition(InstructionSequence* sequence, |
396 InstructionOperand* operand, | 394 const InstructionOperand& operand, |
397 bool might_be_duplicated); | 395 bool might_be_duplicated); |
398 | 396 |
399 void SetSpillStartIndex(int start) { | 397 void SetSpillStartIndex(int start) { |
400 spill_start_index_ = Min(start, spill_start_index_); | 398 spill_start_index_ = Min(start, spill_start_index_); |
401 } | 399 } |
402 | 400 |
403 bool ShouldBeAllocatedBefore(const LiveRange* other) const; | 401 bool ShouldBeAllocatedBefore(const LiveRange* other) const; |
404 bool CanCover(LifetimePosition position) const; | 402 bool CanCover(LifetimePosition position) const; |
405 bool Covers(LifetimePosition position) const; | 403 bool Covers(LifetimePosition position) const; |
406 LifetimePosition FirstIntersection(LiveRange* other) const; | 404 LifetimePosition FirstIntersection(LiveRange* other) const; |
407 | 405 |
408 // Add a new interval or a new use position to this live range. | 406 // Add a new interval or a new use position to this live range. |
409 void EnsureInterval(LifetimePosition start, LifetimePosition end, Zone* zone); | 407 void EnsureInterval(LifetimePosition start, LifetimePosition end, Zone* zone); |
410 void AddUseInterval(LifetimePosition start, LifetimePosition end, Zone* zone); | 408 void AddUseInterval(LifetimePosition start, LifetimePosition end, Zone* zone); |
411 void AddUsePosition(UsePosition* pos); | 409 void AddUsePosition(UsePosition* pos); |
412 | 410 |
413 // Shorten the most recently added interval by setting a new start. | 411 // Shorten the most recently added interval by setting a new start. |
414 void ShortenTo(LifetimePosition start); | 412 void ShortenTo(LifetimePosition start); |
415 | 413 |
416 void Verify() const; | 414 void Verify() const; |
417 | 415 |
418 void ConvertUsesToOperand(const InstructionOperand& op, | 416 void ConvertUsesToOperand(const InstructionOperand& op, |
419 InstructionOperand* spill_op); | 417 const InstructionOperand& spill_op); |
420 void SetUseHints(int register_index); | 418 void SetUseHints(int register_index); |
421 void UnsetUseHints() { SetUseHints(kUnassignedRegister); } | 419 void UnsetUseHints() { SetUseHints(kUnassignedRegister); } |
422 | 420 |
423 private: | 421 private: |
424 struct SpillAtDefinitionList; | 422 struct SpillAtDefinitionList; |
425 | 423 |
426 void set_spill_type(SpillType value) { | 424 void set_spill_type(SpillType value) { |
427 bits_ = SpillTypeField::update(bits_, value); | 425 bits_ = SpillTypeField::update(bits_, value); |
428 } | 426 } |
429 | 427 |
430 void set_spilled(bool value) { bits_ = SpilledField::update(bits_, value); } | 428 void set_spilled(bool value) { bits_ = SpilledField::update(bits_, value); } |
431 | 429 |
432 UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const; | 430 UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const; |
433 void AdvanceLastProcessedMarker(UseInterval* to_start_of, | 431 void AdvanceLastProcessedMarker(UseInterval* to_start_of, |
434 LifetimePosition but_not_past) const; | 432 LifetimePosition but_not_past) const; |
435 | 433 |
436 typedef BitField<bool, 0, 1> SpilledField; | 434 typedef BitField<bool, 0, 1> SpilledField; |
437 typedef BitField<bool, 1, 1> HasSlotUseField; | 435 typedef BitField<bool, 1, 1> HasSlotUseField; |
438 typedef BitField<bool, 2, 1> IsPhiField; | 436 typedef BitField<bool, 2, 1> IsPhiField; |
439 typedef BitField<bool, 3, 1> IsNonLoopPhiField; | 437 typedef BitField<bool, 3, 1> IsNonLoopPhiField; |
440 typedef BitField<RegisterKind, 4, 2> RegisterKindField; | 438 typedef BitField<SpillType, 4, 2> SpillTypeField; |
441 typedef BitField<SpillType, 6, 2> SpillTypeField; | 439 typedef BitField<int32_t, 6, 6> AssignedRegisterField; |
442 typedef BitField<int32_t, 8, 6> AssignedRegisterField; | 440 typedef BitField<MachineType, 12, 15> MachineTypeField; |
443 | 441 |
444 int id_; | 442 int id_; |
445 int spill_start_index_; | 443 int spill_start_index_; |
446 uint32_t bits_; | 444 uint32_t bits_; |
447 UseInterval* last_interval_; | 445 UseInterval* last_interval_; |
448 UseInterval* first_interval_; | 446 UseInterval* first_interval_; |
449 UsePosition* first_pos_; | 447 UsePosition* first_pos_; |
450 LiveRange* parent_; | 448 LiveRange* parent_; |
451 LiveRange* next_; | 449 LiveRange* next_; |
452 union { | 450 union { |
453 // Correct value determined by spill_type() | 451 // Correct value determined by spill_type() |
454 InstructionOperand* spill_operand_; | 452 InstructionOperand* spill_operand_; |
455 SpillRange* spill_range_; | 453 SpillRange* spill_range_; |
456 }; | 454 }; |
457 SpillAtDefinitionList* spills_at_definition_; | 455 SpillAtDefinitionList* spills_at_definition_; |
458 // This is used as a cache, it doesn't affect correctness. | 456 // This is used as a cache, it doesn't affect correctness. |
459 mutable UseInterval* current_interval_; | 457 mutable UseInterval* current_interval_; |
460 // This is used as a cache, it doesn't affect correctness. | 458 // This is used as a cache, it doesn't affect correctness. |
461 mutable UsePosition* last_processed_use_; | 459 mutable UsePosition* last_processed_use_; |
462 // This is used as a cache, it's invalid outside of BuildLiveRanges. | 460 // This is used as a cache, it's invalid outside of BuildLiveRanges. |
463 mutable UsePosition* current_hint_position_; | 461 mutable UsePosition* current_hint_position_; |
464 | 462 |
465 DISALLOW_COPY_AND_ASSIGN(LiveRange); | 463 DISALLOW_COPY_AND_ASSIGN(LiveRange); |
466 }; | 464 }; |
467 | 465 |
468 | 466 |
469 class SpillRange final : public ZoneObject { | 467 class SpillRange final : public ZoneObject { |
470 public: | 468 public: |
| 469 static const int kUnassignedSlot = -1; |
471 SpillRange(LiveRange* range, Zone* zone); | 470 SpillRange(LiveRange* range, Zone* zone); |
472 | 471 |
473 UseInterval* interval() const { return use_interval_; } | 472 UseInterval* interval() const { return use_interval_; } |
474 RegisterKind kind() const { return live_ranges_[0]->kind(); } | 473 // Currently, only 4 or 8 byte slots are supported. |
| 474 int ByteWidth() const; |
475 bool IsEmpty() const { return live_ranges_.empty(); } | 475 bool IsEmpty() const { return live_ranges_.empty(); } |
476 bool TryMerge(SpillRange* other); | 476 bool TryMerge(SpillRange* other); |
477 void SetOperand(AllocatedOperand* op); | 477 |
| 478 void set_assigned_slot(int index) { |
| 479 DCHECK_EQ(kUnassignedSlot, assigned_slot_); |
| 480 assigned_slot_ = index; |
| 481 } |
| 482 int assigned_slot() { |
| 483 DCHECK_NE(kUnassignedSlot, assigned_slot_); |
| 484 return assigned_slot_; |
| 485 } |
478 | 486 |
479 private: | 487 private: |
480 LifetimePosition End() const { return end_position_; } | 488 LifetimePosition End() const { return end_position_; } |
481 ZoneVector<LiveRange*>& live_ranges() { return live_ranges_; } | 489 ZoneVector<LiveRange*>& live_ranges() { return live_ranges_; } |
482 bool IsIntersectingWith(SpillRange* other) const; | 490 bool IsIntersectingWith(SpillRange* other) const; |
483 // Merge intervals, making sure the use intervals are sorted | 491 // Merge intervals, making sure the use intervals are sorted |
484 void MergeDisjointIntervals(UseInterval* other); | 492 void MergeDisjointIntervals(UseInterval* other); |
485 | 493 |
486 ZoneVector<LiveRange*> live_ranges_; | 494 ZoneVector<LiveRange*> live_ranges_; |
487 UseInterval* use_interval_; | 495 UseInterval* use_interval_; |
488 LifetimePosition end_position_; | 496 LifetimePosition end_position_; |
| 497 int assigned_slot_; |
489 | 498 |
490 DISALLOW_COPY_AND_ASSIGN(SpillRange); | 499 DISALLOW_COPY_AND_ASSIGN(SpillRange); |
491 }; | 500 }; |
492 | 501 |
493 | 502 |
494 class RegisterAllocationData final : public ZoneObject { | 503 class RegisterAllocationData final : public ZoneObject { |
495 public: | 504 public: |
496 class PhiMapValue : public ZoneObject { | 505 class PhiMapValue : public ZoneObject { |
497 public: | 506 public: |
498 PhiMapValue(PhiInstruction* phi, const InstructionBlock* block, Zone* zone); | 507 PhiMapValue(PhiInstruction* phi, const InstructionBlock* block, Zone* zone); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
542 // This zone is for datastructures only needed during register allocation | 551 // This zone is for datastructures only needed during register allocation |
543 // phases. | 552 // phases. |
544 Zone* allocation_zone() const { return allocation_zone_; } | 553 Zone* allocation_zone() const { return allocation_zone_; } |
545 // This zone is for InstructionOperands and moves that live beyond register | 554 // This zone is for InstructionOperands and moves that live beyond register |
546 // allocation. | 555 // allocation. |
547 Zone* code_zone() const { return code()->zone(); } | 556 Zone* code_zone() const { return code()->zone(); } |
548 Frame* frame() const { return frame_; } | 557 Frame* frame() const { return frame_; } |
549 const char* debug_name() const { return debug_name_; } | 558 const char* debug_name() const { return debug_name_; } |
550 const RegisterConfiguration* config() const { return config_; } | 559 const RegisterConfiguration* config() const { return config_; } |
551 | 560 |
| 561 MachineType MachineTypeFor(int virtual_register); |
| 562 |
552 LiveRange* LiveRangeFor(int index); | 563 LiveRange* LiveRangeFor(int index); |
| 564 // Creates a new live range. |
| 565 LiveRange* NewLiveRange(int index, MachineType machine_type); |
| 566 LiveRange* NewChildRangeFor(LiveRange* range); |
553 | 567 |
554 SpillRange* AssignSpillRangeToLiveRange(LiveRange* range); | 568 SpillRange* AssignSpillRangeToLiveRange(LiveRange* range); |
555 | 569 |
556 MoveOperands* AddGapMove(int index, Instruction::GapPosition position, | 570 MoveOperands* AddGapMove(int index, Instruction::GapPosition position, |
557 const InstructionOperand& from, | 571 const InstructionOperand& from, |
558 const InstructionOperand& to); | 572 const InstructionOperand& to); |
559 | 573 |
560 bool IsReference(int virtual_register) const { | 574 bool IsReference(int virtual_register) const { |
561 return code()->IsReference(virtual_register); | 575 return code()->IsReference(virtual_register); |
562 } | 576 } |
563 | 577 |
564 bool ExistsUseWithoutDefinition(); | 578 bool ExistsUseWithoutDefinition(); |
565 | 579 |
566 // Creates a new live range. | |
567 LiveRange* NewLiveRange(int index); | |
568 | |
569 void MarkAllocated(RegisterKind kind, int index); | 580 void MarkAllocated(RegisterKind kind, int index); |
570 | 581 |
571 PhiMapValue* InitializePhiMap(const InstructionBlock* block, | 582 PhiMapValue* InitializePhiMap(const InstructionBlock* block, |
572 PhiInstruction* phi); | 583 PhiInstruction* phi); |
573 PhiMapValue* GetPhiMapValueFor(int virtual_register); | 584 PhiMapValue* GetPhiMapValueFor(int virtual_register); |
574 | 585 |
575 private: | 586 private: |
576 Zone* const allocation_zone_; | 587 Zone* const allocation_zone_; |
577 Frame* const frame_; | 588 Frame* const frame_; |
578 InstructionSequence* const code_; | 589 InstructionSequence* const code_; |
579 const char* const debug_name_; | 590 const char* const debug_name_; |
580 const RegisterConfiguration* const config_; | 591 const RegisterConfiguration* const config_; |
581 PhiMap phi_map_; | 592 PhiMap phi_map_; |
582 ZoneVector<BitVector*> live_in_sets_; | 593 ZoneVector<BitVector*> live_in_sets_; |
583 ZoneVector<LiveRange*> live_ranges_; | 594 ZoneVector<LiveRange*> live_ranges_; |
584 ZoneVector<LiveRange*> fixed_live_ranges_; | 595 ZoneVector<LiveRange*> fixed_live_ranges_; |
585 ZoneVector<LiveRange*> fixed_double_live_ranges_; | 596 ZoneVector<LiveRange*> fixed_double_live_ranges_; |
586 ZoneVector<SpillRange*> spill_ranges_; | 597 ZoneVector<SpillRange*> spill_ranges_; |
587 BitVector* assigned_registers_; | 598 BitVector* assigned_registers_; |
588 BitVector* assigned_double_registers_; | 599 BitVector* assigned_double_registers_; |
| 600 int virtual_register_count_; |
589 | 601 |
590 DISALLOW_COPY_AND_ASSIGN(RegisterAllocationData); | 602 DISALLOW_COPY_AND_ASSIGN(RegisterAllocationData); |
591 }; | 603 }; |
592 | 604 |
593 | 605 |
594 class ConstraintBuilder final : public ZoneObject { | 606 class ConstraintBuilder final : public ZoneObject { |
595 public: | 607 public: |
596 explicit ConstraintBuilder(RegisterAllocationData* data); | 608 explicit ConstraintBuilder(RegisterAllocationData* data); |
597 | 609 |
598 // Phase 1 : insert moves to account for fixed register operands. | 610 // Phase 1 : insert moves to account for fixed register operands. |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
657 void ProcessLoopHeader(const InstructionBlock* block, BitVector* live); | 669 void ProcessLoopHeader(const InstructionBlock* block, BitVector* live); |
658 | 670 |
659 static int FixedLiveRangeID(int index) { return -index - 1; } | 671 static int FixedLiveRangeID(int index) { return -index - 1; } |
660 int FixedDoubleLiveRangeID(int index); | 672 int FixedDoubleLiveRangeID(int index); |
661 LiveRange* FixedLiveRangeFor(int index); | 673 LiveRange* FixedLiveRangeFor(int index); |
662 LiveRange* FixedDoubleLiveRangeFor(int index); | 674 LiveRange* FixedDoubleLiveRangeFor(int index); |
663 | 675 |
664 void MapPhiHint(InstructionOperand* operand, UsePosition* use_pos); | 676 void MapPhiHint(InstructionOperand* operand, UsePosition* use_pos); |
665 void ResolvePhiHint(InstructionOperand* operand, UsePosition* use_pos); | 677 void ResolvePhiHint(InstructionOperand* operand, UsePosition* use_pos); |
666 | 678 |
667 // Returns the register kind required by the given virtual register. | |
668 RegisterKind RequiredRegisterKind(int virtual_register) const; | |
669 | |
670 UsePosition* NewUsePosition(LifetimePosition pos, InstructionOperand* operand, | 679 UsePosition* NewUsePosition(LifetimePosition pos, InstructionOperand* operand, |
671 void* hint, UsePositionHintType hint_type); | 680 void* hint, UsePositionHintType hint_type); |
672 UsePosition* NewUsePosition(LifetimePosition pos) { | 681 UsePosition* NewUsePosition(LifetimePosition pos) { |
673 return NewUsePosition(pos, nullptr, nullptr, UsePositionHintType::kNone); | 682 return NewUsePosition(pos, nullptr, nullptr, UsePositionHintType::kNone); |
674 } | 683 } |
675 LiveRange* LiveRangeFor(InstructionOperand* operand); | 684 LiveRange* LiveRangeFor(InstructionOperand* operand); |
676 // Helper methods for building intervals. | 685 // Helper methods for building intervals. |
677 UsePosition* Define(LifetimePosition position, InstructionOperand* operand, | 686 UsePosition* Define(LifetimePosition position, InstructionOperand* operand, |
678 void* hint, UsePositionHintType hint_type); | 687 void* hint, UsePositionHintType hint_type); |
679 void Define(LifetimePosition position, InstructionOperand* operand) { | 688 void Define(LifetimePosition position, InstructionOperand* operand) { |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
907 RegisterAllocationData* const data_; | 916 RegisterAllocationData* const data_; |
908 | 917 |
909 DISALLOW_COPY_AND_ASSIGN(LiveRangeConnector); | 918 DISALLOW_COPY_AND_ASSIGN(LiveRangeConnector); |
910 }; | 919 }; |
911 | 920 |
912 } // namespace compiler | 921 } // namespace compiler |
913 } // namespace internal | 922 } // namespace internal |
914 } // namespace v8 | 923 } // namespace v8 |
915 | 924 |
916 #endif // V8_REGISTER_ALLOCATOR_H_ | 925 #endif // V8_REGISTER_ALLOCATOR_H_ |
OLD | NEW |