| Index: src/lithium-allocator.cc | 
| diff --git a/src/lithium-allocator.cc b/src/lithium-allocator.cc | 
| index 91a98112b61bd60a50b56d98f8ca4eebacdf01ff..303370c2809553c4f7a94d763f13cae7e8d05b43 100644 | 
| --- a/src/lithium-allocator.cc | 
| +++ b/src/lithium-allocator.cc | 
| @@ -196,6 +196,18 @@ UsePosition* LiveRange::NextUsePositionRegisterIsBeneficial( | 
| } | 
|  | 
|  | 
| +UsePosition* LiveRange::PreviousUsePositionRegisterIsBeneficial( | 
| +    LifetimePosition start) { | 
| +  UsePosition* pos = first_pos(); | 
| +  UsePosition* prev = NULL; | 
| +  while (pos != NULL && pos->pos().Value() < start.Value()) { | 
| +    if (pos->RegisterIsBeneficial()) prev = pos; | 
| +    pos = pos->next(); | 
| +  } | 
| +  return prev; | 
| +} | 
| + | 
| + | 
| UsePosition* LiveRange::NextRegisterPosition(LifetimePosition start) { | 
| UsePosition* pos = NextUsePosition(start); | 
| while (pos != NULL && !pos->RequiresRegister()) { | 
| @@ -1936,6 +1948,39 @@ void LAllocator::AllocateBlockedReg(LiveRange* current) { | 
| } | 
|  | 
|  | 
| +LifetimePosition LAllocator::FindOptimalSpillingPos(LiveRange* range, | 
| +                                                    LifetimePosition pos) { | 
| +  HBasicBlock* block = GetBlock(pos.InstructionStart()); | 
| +  HBasicBlock* loop_header = | 
| +      block->IsLoopHeader() ? block : block->parent_loop_header(); | 
| + | 
| +  if (loop_header == NULL) return pos; | 
| + | 
| +  UsePosition* prev_use = | 
| +    range->PreviousUsePositionRegisterIsBeneficial(pos); | 
| + | 
| +  while (loop_header != NULL) { | 
| +    // We are going to spill live range inside the loop. | 
| +    // If possible try to move spilling position backwards to loop header. | 
| +    // This will reduce number of memory moves on the back edge. | 
| +    LifetimePosition loop_start = LifetimePosition::FromInstructionIndex( | 
| +        loop_header->first_instruction_index()); | 
| + | 
| +    if (range->Covers(loop_start)) { | 
| +      if (prev_use == NULL || prev_use->pos().Value() < loop_start.Value()) { | 
| +        // No register beneficial use inside the loop before the pos. | 
| +        pos = loop_start; | 
| +      } | 
| +    } | 
| + | 
| +    // Try hoisting out to an outer loop. | 
| +    loop_header = loop_header->parent_loop_header(); | 
| +  } | 
| + | 
| +  return pos; | 
| +} | 
| + | 
| + | 
| void LAllocator::SplitAndSpillIntersecting(LiveRange* current) { | 
| ASSERT(current->HasRegisterAssigned()); | 
| int reg = current->assigned_register(); | 
| @@ -1944,10 +1989,11 @@ void LAllocator::SplitAndSpillIntersecting(LiveRange* current) { | 
| LiveRange* range = active_live_ranges_[i]; | 
| if (range->assigned_register() == reg) { | 
| UsePosition* next_pos = range->NextRegisterPosition(current->Start()); | 
| +      LifetimePosition spill_pos = FindOptimalSpillingPos(range, split_pos); | 
| if (next_pos == NULL) { | 
| -        SpillAfter(range, split_pos); | 
| +        SpillAfter(range, spill_pos); | 
| } else { | 
| -        SpillBetween(range, split_pos, next_pos->pos()); | 
| +        SpillBetween(range, spill_pos, next_pos->pos()); | 
| } | 
| ActiveToHandled(range); | 
| --i; | 
|  |