| OLD | NEW | 
|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/lithium-allocator.h" | 5 #include "src/lithium-allocator.h" | 
| 6 | 6 | 
| 7 #include "src/hydrogen.h" | 7 #include "src/hydrogen.h" | 
| 8 #include "src/lithium-inl.h" | 8 #include "src/lithium-inl.h" | 
| 9 #include "src/lithium-allocator-inl.h" | 9 #include "src/lithium-allocator-inl.h" | 
|  | 10 #include "src/register-configuration.h" | 
| 10 #include "src/string-stream.h" | 11 #include "src/string-stream.h" | 
| 11 | 12 | 
| 12 namespace v8 { | 13 namespace v8 { | 
| 13 namespace internal { | 14 namespace internal { | 
| 14 | 15 | 
| 15 static inline LifetimePosition Min(LifetimePosition a, LifetimePosition b) { | 16 static inline LifetimePosition Min(LifetimePosition a, LifetimePosition b) { | 
| 16   return a.Value() < b.Value() ? a : b; | 17   return a.Value() < b.Value() ? a : b; | 
| 17 } | 18 } | 
| 18 | 19 | 
| 19 | 20 | 
| (...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 578   while (!iterator.Done()) { | 579   while (!iterator.Done()) { | 
| 579     int operand_index = iterator.Current(); | 580     int operand_index = iterator.Current(); | 
| 580     LiveRange* range = LiveRangeFor(operand_index); | 581     LiveRange* range = LiveRangeFor(operand_index); | 
| 581     range->AddUseInterval(start, end, zone()); | 582     range->AddUseInterval(start, end, zone()); | 
| 582     iterator.Advance(); | 583     iterator.Advance(); | 
| 583   } | 584   } | 
| 584 } | 585 } | 
| 585 | 586 | 
| 586 | 587 | 
| 587 int LAllocator::FixedDoubleLiveRangeID(int index) { | 588 int LAllocator::FixedDoubleLiveRangeID(int index) { | 
| 588   return -index - 1 - Register::kMaxNumAllocatableRegisters; | 589   return -index - 1 - Register::kNumRegisters; | 
| 589 } | 590 } | 
| 590 | 591 | 
| 591 | 592 | 
| 592 LOperand* LAllocator::AllocateFixed(LUnallocated* operand, | 593 LOperand* LAllocator::AllocateFixed(LUnallocated* operand, | 
| 593                                     int pos, | 594                                     int pos, | 
| 594                                     bool is_tagged) { | 595                                     bool is_tagged) { | 
| 595   TraceAlloc("Allocating fixed reg for op %d\n", operand->virtual_register()); | 596   TraceAlloc("Allocating fixed reg for op %d\n", operand->virtual_register()); | 
| 596   DCHECK(operand->HasFixedPolicy()); | 597   DCHECK(operand->HasFixedPolicy()); | 
| 597   if (operand->HasFixedSlotPolicy()) { | 598   if (operand->HasFixedSlotPolicy()) { | 
| 598     operand->ConvertTo(LOperand::STACK_SLOT, operand->fixed_slot_index()); | 599     operand->ConvertTo(LOperand::STACK_SLOT, operand->fixed_slot_index()); | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 610     LInstruction* instr = InstructionAt(pos); | 611     LInstruction* instr = InstructionAt(pos); | 
| 611     if (instr->HasPointerMap()) { | 612     if (instr->HasPointerMap()) { | 
| 612       instr->pointer_map()->RecordPointer(operand, chunk()->zone()); | 613       instr->pointer_map()->RecordPointer(operand, chunk()->zone()); | 
| 613     } | 614     } | 
| 614   } | 615   } | 
| 615   return operand; | 616   return operand; | 
| 616 } | 617 } | 
| 617 | 618 | 
| 618 | 619 | 
| 619 LiveRange* LAllocator::FixedLiveRangeFor(int index) { | 620 LiveRange* LAllocator::FixedLiveRangeFor(int index) { | 
| 620   DCHECK(index < Register::kMaxNumAllocatableRegisters); | 621   DCHECK(index < Register::kNumRegisters); | 
| 621   LiveRange* result = fixed_live_ranges_[index]; | 622   LiveRange* result = fixed_live_ranges_[index]; | 
| 622   if (result == NULL) { | 623   if (result == NULL) { | 
| 623     result = new(zone()) LiveRange(FixedLiveRangeID(index), chunk()->zone()); | 624     result = new(zone()) LiveRange(FixedLiveRangeID(index), chunk()->zone()); | 
| 624     DCHECK(result->IsFixed()); | 625     DCHECK(result->IsFixed()); | 
| 625     result->kind_ = GENERAL_REGISTERS; | 626     result->kind_ = GENERAL_REGISTERS; | 
| 626     SetLiveRangeAssignedRegister(result, index); | 627     SetLiveRangeAssignedRegister(result, index); | 
| 627     fixed_live_ranges_[index] = result; | 628     fixed_live_ranges_[index] = result; | 
| 628   } | 629   } | 
| 629   return result; | 630   return result; | 
| 630 } | 631 } | 
| 631 | 632 | 
| 632 | 633 | 
| 633 LiveRange* LAllocator::FixedDoubleLiveRangeFor(int index) { | 634 LiveRange* LAllocator::FixedDoubleLiveRangeFor(int index) { | 
| 634   DCHECK(index < DoubleRegister::NumAllocatableRegisters()); | 635   DCHECK(index < DoubleRegister::kMaxNumRegisters); | 
| 635   LiveRange* result = fixed_double_live_ranges_[index]; | 636   LiveRange* result = fixed_double_live_ranges_[index]; | 
| 636   if (result == NULL) { | 637   if (result == NULL) { | 
| 637     result = new(zone()) LiveRange(FixedDoubleLiveRangeID(index), | 638     result = new(zone()) LiveRange(FixedDoubleLiveRangeID(index), | 
| 638                                    chunk()->zone()); | 639                                    chunk()->zone()); | 
| 639     DCHECK(result->IsFixed()); | 640     DCHECK(result->IsFixed()); | 
| 640     result->kind_ = DOUBLE_REGISTERS; | 641     result->kind_ = DOUBLE_REGISTERS; | 
| 641     SetLiveRangeAssignedRegister(result, index); | 642     SetLiveRangeAssignedRegister(result, index); | 
| 642     fixed_double_live_ranges_[index] = result; | 643     fixed_double_live_ranges_[index] = result; | 
| 643   } | 644   } | 
| 644   return result; | 645   return result; | 
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 932       if (instr != NULL) { | 933       if (instr != NULL) { | 
| 933         LOperand* output = instr->Output(); | 934         LOperand* output = instr->Output(); | 
| 934         if (output != NULL) { | 935         if (output != NULL) { | 
| 935           if (output->IsUnallocated()) { | 936           if (output->IsUnallocated()) { | 
| 936             live->Remove(LUnallocated::cast(output)->virtual_register()); | 937             live->Remove(LUnallocated::cast(output)->virtual_register()); | 
| 937           } | 938           } | 
| 938           Define(curr_position, output, NULL); | 939           Define(curr_position, output, NULL); | 
| 939         } | 940         } | 
| 940 | 941 | 
| 941         if (instr->ClobbersRegisters()) { | 942         if (instr->ClobbersRegisters()) { | 
| 942           for (int i = 0; i < Register::kMaxNumAllocatableRegisters; ++i) { | 943           for (int i = 0; i < Register::kNumRegisters; ++i) { | 
| 943             if (output == NULL || !output->IsRegister() || | 944             if (Register::from_code(i).IsAllocatable()) { | 
| 944                 output->index() != i) { | 945               if (output == NULL || !output->IsRegister() || | 
| 945               LiveRange* range = FixedLiveRangeFor(i); | 946                   output->index() != i) { | 
| 946               range->AddUseInterval(curr_position, | 947                 LiveRange* range = FixedLiveRangeFor(i); | 
| 947                                     curr_position.InstructionEnd(), | 948                 range->AddUseInterval(curr_position, | 
| 948                                     zone()); | 949                                       curr_position.InstructionEnd(), zone()); | 
|  | 950               } | 
| 949             } | 951             } | 
| 950           } | 952           } | 
| 951         } | 953         } | 
| 952 | 954 | 
| 953         if (instr->ClobbersDoubleRegisters(isolate())) { | 955         if (instr->ClobbersDoubleRegisters(isolate())) { | 
| 954           for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); ++i) { | 956           for (int i = 0; i < DoubleRegister::kMaxNumRegisters; ++i) { | 
| 955             if (output == NULL || !output->IsDoubleRegister() || | 957             if (DoubleRegister::from_code(i).IsAllocatable()) { | 
| 956                 output->index() != i) { | 958               if (output == NULL || !output->IsDoubleRegister() || | 
| 957               LiveRange* range = FixedDoubleLiveRangeFor(i); | 959                   output->index() != i) { | 
| 958               range->AddUseInterval(curr_position, | 960                 LiveRange* range = FixedDoubleLiveRangeFor(i); | 
| 959                                     curr_position.InstructionEnd(), | 961                 range->AddUseInterval(curr_position, | 
| 960                                     zone()); | 962                                       curr_position.InstructionEnd(), zone()); | 
|  | 963               } | 
| 961             } | 964             } | 
| 962           } | 965           } | 
| 963         } | 966         } | 
| 964 | 967 | 
| 965         for (UseIterator it(instr); !it.Done(); it.Advance()) { | 968         for (UseIterator it(instr); !it.Done(); it.Advance()) { | 
| 966           LOperand* input = it.Current(); | 969           LOperand* input = it.Current(); | 
| 967 | 970 | 
| 968           LifetimePosition use_pos; | 971           LifetimePosition use_pos; | 
| 969           if (input->IsUnallocated() && | 972           if (input->IsUnallocated() && | 
| 970               LUnallocated::cast(input)->IsUsedAtStart()) { | 973               LUnallocated::cast(input)->IsUsedAtStart()) { | 
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1062         AddMove(phi_operand, live_range->GetSpillOperand(), chunk()->zone()); | 1065         AddMove(phi_operand, live_range->GetSpillOperand(), chunk()->zone()); | 
| 1063     live_range->SetSpillStartIndex(phi->block()->first_instruction_index()); | 1066     live_range->SetSpillStartIndex(phi->block()->first_instruction_index()); | 
| 1064   } | 1067   } | 
| 1065 } | 1068 } | 
| 1066 | 1069 | 
| 1067 | 1070 | 
| 1068 bool LAllocator::Allocate(LChunk* chunk) { | 1071 bool LAllocator::Allocate(LChunk* chunk) { | 
| 1069   DCHECK(chunk_ == NULL); | 1072   DCHECK(chunk_ == NULL); | 
| 1070   chunk_ = static_cast<LPlatformChunk*>(chunk); | 1073   chunk_ = static_cast<LPlatformChunk*>(chunk); | 
| 1071   assigned_registers_ = | 1074   assigned_registers_ = | 
| 1072       new(chunk->zone()) BitVector(Register::NumAllocatableRegisters(), | 1075       new (chunk->zone()) BitVector(Register::kNumRegisters, chunk->zone()); | 
| 1073                                    chunk->zone()); | 1076   assigned_double_registers_ = new (chunk->zone()) | 
| 1074   assigned_double_registers_ = | 1077       BitVector(DoubleRegister::kMaxNumRegisters, chunk->zone()); | 
| 1075       new(chunk->zone()) BitVector(DoubleRegister::NumAllocatableRegisters(), |  | 
| 1076                                    chunk->zone()); |  | 
| 1077   MeetRegisterConstraints(); | 1078   MeetRegisterConstraints(); | 
| 1078   if (!AllocationOk()) return false; | 1079   if (!AllocationOk()) return false; | 
| 1079   ResolvePhis(); | 1080   ResolvePhis(); | 
| 1080   BuildLiveRanges(); | 1081   BuildLiveRanges(); | 
| 1081   AllocateGeneralRegisters(); | 1082   AllocateGeneralRegisters(); | 
| 1082   if (!AllocationOk()) return false; | 1083   if (!AllocationOk()) return false; | 
| 1083   AllocateDoubleRegisters(); | 1084   AllocateDoubleRegisters(); | 
| 1084   if (!AllocationOk()) return false; | 1085   if (!AllocationOk()) return false; | 
| 1085   PopulatePointerMaps(); | 1086   PopulatePointerMaps(); | 
| 1086   ConnectRanges(); | 1087   ConnectRanges(); | 
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1453         DCHECK(!operand->IsStackSlot()); | 1454         DCHECK(!operand->IsStackSlot()); | 
| 1454         map->RecordPointer(operand, chunk()->zone()); | 1455         map->RecordPointer(operand, chunk()->zone()); | 
| 1455       } | 1456       } | 
| 1456     } | 1457     } | 
| 1457   } | 1458   } | 
| 1458 } | 1459 } | 
| 1459 | 1460 | 
| 1460 | 1461 | 
| 1461 void LAllocator::AllocateGeneralRegisters() { | 1462 void LAllocator::AllocateGeneralRegisters() { | 
| 1462   LAllocatorPhase phase("L_Allocate general registers", this); | 1463   LAllocatorPhase phase("L_Allocate general registers", this); | 
| 1463   num_registers_ = Register::NumAllocatableRegisters(); | 1464   num_registers_ = | 
|  | 1465       RegisterConfiguration::ArchDefault()->num_allocatable_general_registers(); | 
|  | 1466   allocatable_register_codes_ = | 
|  | 1467       RegisterConfiguration::ArchDefault()->allocatable_general_codes(); | 
| 1464   mode_ = GENERAL_REGISTERS; | 1468   mode_ = GENERAL_REGISTERS; | 
| 1465   AllocateRegisters(); | 1469   AllocateRegisters(); | 
| 1466 } | 1470 } | 
| 1467 | 1471 | 
| 1468 | 1472 | 
| 1469 void LAllocator::AllocateDoubleRegisters() { | 1473 void LAllocator::AllocateDoubleRegisters() { | 
| 1470   LAllocatorPhase phase("L_Allocate double registers", this); | 1474   LAllocatorPhase phase("L_Allocate double registers", this); | 
| 1471   num_registers_ = DoubleRegister::NumAllocatableRegisters(); | 1475   num_registers_ = | 
|  | 1476       RegisterConfiguration::ArchDefault()->num_allocatable_double_registers(); | 
|  | 1477   allocatable_register_codes_ = | 
|  | 1478       RegisterConfiguration::ArchDefault()->allocatable_double_codes(); | 
| 1472   mode_ = DOUBLE_REGISTERS; | 1479   mode_ = DOUBLE_REGISTERS; | 
| 1473   AllocateRegisters(); | 1480   AllocateRegisters(); | 
| 1474 } | 1481 } | 
| 1475 | 1482 | 
| 1476 | 1483 | 
| 1477 void LAllocator::AllocateRegisters() { | 1484 void LAllocator::AllocateRegisters() { | 
| 1478   DCHECK(unhandled_live_ranges_.is_empty()); | 1485   DCHECK(unhandled_live_ranges_.is_empty()); | 
| 1479 | 1486 | 
| 1480   for (int i = 0; i < live_ranges_.length(); ++i) { | 1487   for (int i = 0; i < live_ranges_.length(); ++i) { | 
| 1481     if (live_ranges_[i] != NULL) { | 1488     if (live_ranges_[i] != NULL) { | 
| 1482       if (live_ranges_[i]->Kind() == mode_) { | 1489       if (live_ranges_[i]->Kind() == mode_) { | 
| 1483         AddToUnhandledUnsorted(live_ranges_[i]); | 1490         AddToUnhandledUnsorted(live_ranges_[i]); | 
| 1484       } | 1491       } | 
| 1485     } | 1492     } | 
| 1486   } | 1493   } | 
| 1487   SortUnhandled(); | 1494   SortUnhandled(); | 
| 1488   DCHECK(UnhandledIsSorted()); | 1495   DCHECK(UnhandledIsSorted()); | 
| 1489 | 1496 | 
| 1490   DCHECK(reusable_slots_.is_empty()); | 1497   DCHECK(reusable_slots_.is_empty()); | 
| 1491   DCHECK(active_live_ranges_.is_empty()); | 1498   DCHECK(active_live_ranges_.is_empty()); | 
| 1492   DCHECK(inactive_live_ranges_.is_empty()); | 1499   DCHECK(inactive_live_ranges_.is_empty()); | 
| 1493 | 1500 | 
| 1494   if (mode_ == DOUBLE_REGISTERS) { | 1501   if (mode_ == DOUBLE_REGISTERS) { | 
| 1495     for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); ++i) { | 1502     for (int i = 0; i < fixed_double_live_ranges_.length(); ++i) { | 
| 1496       LiveRange* current = fixed_double_live_ranges_.at(i); | 1503       LiveRange* current = fixed_double_live_ranges_.at(i); | 
| 1497       if (current != NULL) { | 1504       if (current != NULL) { | 
| 1498         AddToInactive(current); | 1505         AddToInactive(current); | 
| 1499       } | 1506       } | 
| 1500     } | 1507     } | 
| 1501   } else { | 1508   } else { | 
| 1502     DCHECK(mode_ == GENERAL_REGISTERS); | 1509     DCHECK(mode_ == GENERAL_REGISTERS); | 
| 1503     for (int i = 0; i < fixed_live_ranges_.length(); ++i) { | 1510     for (int i = 0; i < fixed_live_ranges_.length(); ++i) { | 
| 1504       LiveRange* current = fixed_live_ranges_.at(i); | 1511       LiveRange* current = fixed_live_ranges_.at(i); | 
| 1505       if (current != NULL) { | 1512       if (current != NULL) { | 
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1579   } | 1586   } | 
| 1580 | 1587 | 
| 1581   reusable_slots_.Rewind(0); | 1588   reusable_slots_.Rewind(0); | 
| 1582   active_live_ranges_.Rewind(0); | 1589   active_live_ranges_.Rewind(0); | 
| 1583   inactive_live_ranges_.Rewind(0); | 1590   inactive_live_ranges_.Rewind(0); | 
| 1584 } | 1591 } | 
| 1585 | 1592 | 
| 1586 | 1593 | 
| 1587 const char* LAllocator::RegisterName(int allocation_index) { | 1594 const char* LAllocator::RegisterName(int allocation_index) { | 
| 1588   if (mode_ == GENERAL_REGISTERS) { | 1595   if (mode_ == GENERAL_REGISTERS) { | 
| 1589     return Register::AllocationIndexToString(allocation_index); | 1596     return Register::from_code(allocation_index).ToString(); | 
| 1590   } else { | 1597   } else { | 
| 1591     return DoubleRegister::AllocationIndexToString(allocation_index); | 1598     return DoubleRegister::from_code(allocation_index).ToString(); | 
| 1592   } | 1599   } | 
| 1593 } | 1600 } | 
| 1594 | 1601 | 
| 1595 | 1602 | 
| 1596 void LAllocator::TraceAlloc(const char* msg, ...) { | 1603 void LAllocator::TraceAlloc(const char* msg, ...) { | 
| 1597   if (FLAG_trace_alloc) { | 1604   if (FLAG_trace_alloc) { | 
| 1598     va_list arguments; | 1605     va_list arguments; | 
| 1599     va_start(arguments, msg); | 1606     va_start(arguments, msg); | 
| 1600     base::OS::VPrint(msg, arguments); | 1607     base::OS::VPrint(msg, arguments); | 
| 1601     va_end(arguments); | 1608     va_end(arguments); | 
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1743 | 1750 | 
| 1744 | 1751 | 
| 1745 void LAllocator::InactiveToActive(LiveRange* range) { | 1752 void LAllocator::InactiveToActive(LiveRange* range) { | 
| 1746   DCHECK(inactive_live_ranges_.Contains(range)); | 1753   DCHECK(inactive_live_ranges_.Contains(range)); | 
| 1747   inactive_live_ranges_.RemoveElement(range); | 1754   inactive_live_ranges_.RemoveElement(range); | 
| 1748   active_live_ranges_.Add(range, zone()); | 1755   active_live_ranges_.Add(range, zone()); | 
| 1749   TraceAlloc("Moving live range %d from inactive to active\n", range->id()); | 1756   TraceAlloc("Moving live range %d from inactive to active\n", range->id()); | 
| 1750 } | 1757 } | 
| 1751 | 1758 | 
| 1752 | 1759 | 
| 1753 // TryAllocateFreeReg and AllocateBlockedReg assume this | 1760 bool LAllocator::TryAllocateFreeReg(LiveRange* current) { | 
| 1754 // when allocating local arrays. | 1761   DCHECK(DoubleRegister::kMaxNumRegisters >= Register::kNumRegisters); | 
| 1755 STATIC_ASSERT(DoubleRegister::kMaxNumAllocatableRegisters >= |  | 
| 1756               Register::kMaxNumAllocatableRegisters); |  | 
| 1757 | 1762 | 
|  | 1763   LifetimePosition free_until_pos[DoubleRegister::kMaxNumRegisters]; | 
| 1758 | 1764 | 
| 1759 bool LAllocator::TryAllocateFreeReg(LiveRange* current) { | 1765   for (int i = 0; i < DoubleRegister::kMaxNumRegisters; i++) { | 
| 1760   LifetimePosition free_until_pos[DoubleRegister::kMaxNumAllocatableRegisters]; |  | 
| 1761 |  | 
| 1762   for (int i = 0; i < num_registers_; i++) { |  | 
| 1763     free_until_pos[i] = LifetimePosition::MaxPosition(); | 1766     free_until_pos[i] = LifetimePosition::MaxPosition(); | 
| 1764   } | 1767   } | 
| 1765 | 1768 | 
| 1766   for (int i = 0; i < active_live_ranges_.length(); ++i) { | 1769   for (int i = 0; i < active_live_ranges_.length(); ++i) { | 
| 1767     LiveRange* cur_active = active_live_ranges_.at(i); | 1770     LiveRange* cur_active = active_live_ranges_.at(i); | 
| 1768     free_until_pos[cur_active->assigned_register()] = | 1771     free_until_pos[cur_active->assigned_register()] = | 
| 1769         LifetimePosition::FromInstructionIndex(0); | 1772         LifetimePosition::FromInstructionIndex(0); | 
| 1770   } | 1773   } | 
| 1771 | 1774 | 
| 1772   for (int i = 0; i < inactive_live_ranges_.length(); ++i) { | 1775   for (int i = 0; i < inactive_live_ranges_.length(); ++i) { | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 1793     if (free_until_pos[register_index].Value() >= current->End().Value()) { | 1796     if (free_until_pos[register_index].Value() >= current->End().Value()) { | 
| 1794       TraceAlloc("Assigning preferred reg %s to live range %d\n", | 1797       TraceAlloc("Assigning preferred reg %s to live range %d\n", | 
| 1795                  RegisterName(register_index), | 1798                  RegisterName(register_index), | 
| 1796                  current->id()); | 1799                  current->id()); | 
| 1797       SetLiveRangeAssignedRegister(current, register_index); | 1800       SetLiveRangeAssignedRegister(current, register_index); | 
| 1798       return true; | 1801       return true; | 
| 1799     } | 1802     } | 
| 1800   } | 1803   } | 
| 1801 | 1804 | 
| 1802   // Find the register which stays free for the longest time. | 1805   // Find the register which stays free for the longest time. | 
| 1803   int reg = 0; | 1806   int reg = allocatable_register_codes_[0]; | 
| 1804   for (int i = 1; i < RegisterCount(); ++i) { | 1807   for (int i = 1; i < RegisterCount(); ++i) { | 
| 1805     if (free_until_pos[i].Value() > free_until_pos[reg].Value()) { | 1808     int code = allocatable_register_codes_[i]; | 
| 1806       reg = i; | 1809     if (free_until_pos[code].Value() > free_until_pos[reg].Value()) { | 
|  | 1810       reg = code; | 
| 1807     } | 1811     } | 
| 1808   } | 1812   } | 
| 1809 | 1813 | 
| 1810   LifetimePosition pos = free_until_pos[reg]; | 1814   LifetimePosition pos = free_until_pos[reg]; | 
| 1811 | 1815 | 
| 1812   if (pos.Value() <= current->Start().Value()) { | 1816   if (pos.Value() <= current->Start().Value()) { | 
| 1813     // All registers are blocked. | 1817     // All registers are blocked. | 
| 1814     return false; | 1818     return false; | 
| 1815   } | 1819   } | 
| 1816 | 1820 | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 1838 void LAllocator::AllocateBlockedReg(LiveRange* current) { | 1842 void LAllocator::AllocateBlockedReg(LiveRange* current) { | 
| 1839   UsePosition* register_use = current->NextRegisterPosition(current->Start()); | 1843   UsePosition* register_use = current->NextRegisterPosition(current->Start()); | 
| 1840   if (register_use == NULL) { | 1844   if (register_use == NULL) { | 
| 1841     // There is no use in the current live range that requires a register. | 1845     // There is no use in the current live range that requires a register. | 
| 1842     // We can just spill it. | 1846     // We can just spill it. | 
| 1843     Spill(current); | 1847     Spill(current); | 
| 1844     return; | 1848     return; | 
| 1845   } | 1849   } | 
| 1846 | 1850 | 
| 1847 | 1851 | 
| 1848   LifetimePosition use_pos[DoubleRegister::kMaxNumAllocatableRegisters]; | 1852   LifetimePosition use_pos[DoubleRegister::kMaxNumRegisters]; | 
| 1849   LifetimePosition block_pos[DoubleRegister::kMaxNumAllocatableRegisters]; | 1853   LifetimePosition block_pos[DoubleRegister::kMaxNumRegisters]; | 
| 1850 | 1854 | 
| 1851   for (int i = 0; i < num_registers_; i++) { | 1855   for (int i = 0; i < DoubleRegister::kMaxNumRegisters; i++) { | 
| 1852     use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition(); | 1856     use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition(); | 
| 1853   } | 1857   } | 
| 1854 | 1858 | 
| 1855   for (int i = 0; i < active_live_ranges_.length(); ++i) { | 1859   for (int i = 0; i < active_live_ranges_.length(); ++i) { | 
| 1856     LiveRange* range = active_live_ranges_[i]; | 1860     LiveRange* range = active_live_ranges_[i]; | 
| 1857     int cur_reg = range->assigned_register(); | 1861     int cur_reg = range->assigned_register(); | 
| 1858     if (range->IsFixed() || !range->CanBeSpilled(current->Start())) { | 1862     if (range->IsFixed() || !range->CanBeSpilled(current->Start())) { | 
| 1859       block_pos[cur_reg] = use_pos[cur_reg] = | 1863       block_pos[cur_reg] = use_pos[cur_reg] = | 
| 1860           LifetimePosition::FromInstructionIndex(0); | 1864           LifetimePosition::FromInstructionIndex(0); | 
| 1861     } else { | 1865     } else { | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 1876     if (!next_intersection.IsValid()) continue; | 1880     if (!next_intersection.IsValid()) continue; | 
| 1877     int cur_reg = range->assigned_register(); | 1881     int cur_reg = range->assigned_register(); | 
| 1878     if (range->IsFixed()) { | 1882     if (range->IsFixed()) { | 
| 1879       block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection); | 1883       block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection); | 
| 1880       use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]); | 1884       use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]); | 
| 1881     } else { | 1885     } else { | 
| 1882       use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection); | 1886       use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection); | 
| 1883     } | 1887     } | 
| 1884   } | 1888   } | 
| 1885 | 1889 | 
| 1886   int reg = 0; | 1890   int reg = allocatable_register_codes_[0]; | 
| 1887   for (int i = 1; i < RegisterCount(); ++i) { | 1891   for (int i = 1; i < RegisterCount(); ++i) { | 
| 1888     if (use_pos[i].Value() > use_pos[reg].Value()) { | 1892     int code = allocatable_register_codes_[i]; | 
| 1889       reg = i; | 1893     if (use_pos[code].Value() > use_pos[reg].Value()) { | 
|  | 1894       reg = code; | 
| 1890     } | 1895     } | 
| 1891   } | 1896   } | 
| 1892 | 1897 | 
| 1893   LifetimePosition pos = use_pos[reg]; | 1898   LifetimePosition pos = use_pos[reg]; | 
| 1894 | 1899 | 
| 1895   if (pos.Value() < register_use->pos().Value()) { | 1900   if (pos.Value() < register_use->pos().Value()) { | 
| 1896     // All registers are blocked before the first use that requires a register. | 1901     // All registers are blocked before the first use that requires a register. | 
| 1897     // Spill starting part of live range up to that use. | 1902     // Spill starting part of live range up to that use. | 
| 1898     SpillBetween(current, current->Start(), register_use->pos()); | 1903     SpillBetween(current, current->Start(), register_use->pos()); | 
| 1899     return; | 1904     return; | 
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2180   } | 2185   } | 
| 2181 | 2186 | 
| 2182 #ifdef DEBUG | 2187 #ifdef DEBUG | 
| 2183   if (allocator_ != NULL) allocator_->Verify(); | 2188   if (allocator_ != NULL) allocator_->Verify(); | 
| 2184 #endif | 2189 #endif | 
| 2185 } | 2190 } | 
| 2186 | 2191 | 
| 2187 | 2192 | 
| 2188 }  // namespace internal | 2193 }  // namespace internal | 
| 2189 }  // namespace v8 | 2194 }  // namespace v8 | 
| OLD | NEW | 
|---|