| Index: src/compiler/register-allocator.cc
|
| diff --git a/src/compiler/register-allocator.cc b/src/compiler/register-allocator.cc
|
| index 59d80c6f7c6fbfadda50fde5fac33da698b22892..283603a44e1728e6a9c8ae82b79fa053415a5c73 100644
|
| --- a/src/compiler/register-allocator.cc
|
| +++ b/src/compiler/register-allocator.cc
|
| @@ -881,6 +881,8 @@ void SpillRange::MergeDisjointIntervals(UseInterval* other, Zone* zone) {
|
|
|
|
|
| void RegisterAllocator::ReuseSpillSlots() {
|
| + DCHECK(FLAG_turbo_reuse_spill_slots);
|
| +
|
| // Merge disjoint spill ranges
|
| for (int i = 0; i < spill_ranges_.length(); i++) {
|
| SpillRange* range = spill_ranges_.at(i);
|
| @@ -915,6 +917,7 @@ void RegisterAllocator::ReuseSpillSlots() {
|
|
|
|
|
| SpillRange* RegisterAllocator::AssignSpillRangeToLiveRange(LiveRange* range) {
|
| + DCHECK(FLAG_turbo_reuse_spill_slots);
|
| int spill_id = spill_ranges_.length();
|
| SpillRange* spill_range =
|
| new (local_zone()) SpillRange(range, spill_id, local_zone());
|
| @@ -1932,10 +1935,40 @@ bool RegisterAllocator::UnhandledIsSorted() {
|
| }
|
|
|
|
|
| +void RegisterAllocator::FreeSpillSlot(LiveRange* range) {
|
| + DCHECK(!FLAG_turbo_reuse_spill_slots);
|
| + // Check that we are the last range.
|
| + if (range->next() != NULL) return;
|
| +
|
| + if (!range->TopLevel()->HasAllocatedSpillOperand()) return;
|
| +
|
| + InstructionOperand* spill_operand = range->TopLevel()->GetSpillOperand();
|
| + if (spill_operand->IsConstant()) return;
|
| + if (spill_operand->index() >= 0) {
|
| + reusable_slots_.Add(range, local_zone());
|
| + }
|
| +}
|
| +
|
| +
|
| +InstructionOperand* RegisterAllocator::TryReuseSpillSlot(LiveRange* range) {
|
| + DCHECK(!FLAG_turbo_reuse_spill_slots);
|
| + if (reusable_slots_.is_empty()) return NULL;
|
| + if (reusable_slots_.first()->End().Value() >
|
| + range->TopLevel()->Start().Value()) {
|
| + return NULL;
|
| + }
|
| + InstructionOperand* result =
|
| + reusable_slots_.first()->TopLevel()->GetSpillOperand();
|
| + reusable_slots_.Remove(0);
|
| + return result;
|
| +}
|
| +
|
| +
|
| void RegisterAllocator::ActiveToHandled(LiveRange* range) {
|
| DCHECK(active_live_ranges_.Contains(range));
|
| active_live_ranges_.RemoveElement(range);
|
| TraceAlloc("Moving live range %d from active to handled\n", range->id());
|
| + if (!FLAG_turbo_reuse_spill_slots) FreeSpillSlot(range);
|
| }
|
|
|
|
|
| @@ -1951,6 +1984,7 @@ void RegisterAllocator::InactiveToHandled(LiveRange* range) {
|
| DCHECK(inactive_live_ranges_.Contains(range));
|
| inactive_live_ranges_.RemoveElement(range);
|
| TraceAlloc("Moving live range %d from inactive to handled\n", range->id());
|
| + if (!FLAG_turbo_reuse_spill_slots) FreeSpillSlot(range);
|
| }
|
|
|
|
|
| @@ -2335,7 +2369,23 @@ void RegisterAllocator::Spill(LiveRange* range) {
|
| LiveRange* first = range->TopLevel();
|
|
|
| if (!first->HasAllocatedSpillOperand()) {
|
| - AssignSpillRangeToLiveRange(first);
|
| + if (FLAG_turbo_reuse_spill_slots) {
|
| + AssignSpillRangeToLiveRange(first);
|
| + } else {
|
| + InstructionOperand* op = TryReuseSpillSlot(range);
|
| + if (op == NULL) {
|
| + // Allocate a new operand referring to the spill slot.
|
| + RegisterKind kind = range->Kind();
|
| + int index = frame()->AllocateSpillSlot(kind == DOUBLE_REGISTERS);
|
| + if (kind == DOUBLE_REGISTERS) {
|
| + op = DoubleStackSlotOperand::Create(index, local_zone());
|
| + } else {
|
| + DCHECK(kind == GENERAL_REGISTERS);
|
| + op = StackSlotOperand::Create(index, local_zone());
|
| + }
|
| + }
|
| + first->SetSpillOperand(op);
|
| + }
|
| }
|
| range->MakeSpilled(code_zone());
|
| }
|
|
|