| Index: src/ia32/virtual-frame-ia32.cc
 | 
| ===================================================================
 | 
| --- src/ia32/virtual-frame-ia32.cc	(revision 3920)
 | 
| +++ src/ia32/virtual-frame-ia32.cc	(working copy)
 | 
| @@ -948,47 +948,38 @@
 | 
|  }
 | 
|  
 | 
|  
 | 
| -Result VirtualFrame::CallStoreIC() {
 | 
| -  // Name, value, and receiver are on top of the frame.  The IC
 | 
| -  // expects name in ecx, value in eax, and receiver in edx.
 | 
| +Result VirtualFrame::CallStoreIC(Handle<String> name, bool is_contextual) {
 | 
| +  // Value and (if not contextual) receiver are on top of the frame.
 | 
| +  //  The IC expects name in ecx, value in eax, and receiver in edx.
 | 
|    Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
 | 
| -  Result name = Pop();
 | 
|    Result value = Pop();
 | 
| -  Result receiver = Pop();
 | 
| -  PrepareForCall(0, 0);
 | 
| +  if (is_contextual) {
 | 
| +    PrepareForCall(0, 0);
 | 
| +    value.ToRegister(eax);
 | 
| +    __ mov(edx, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
 | 
| +    __ mov(ecx, name);
 | 
| +  } else {
 | 
| +    Result receiver = Pop();
 | 
| +    PrepareForCall(0, 0);
 | 
|  
 | 
| -  // Optimized for case in which name is a constant value.
 | 
| -  if (name.is_register() && (name.reg().is(edx) || name.reg().is(eax))) {
 | 
| -    if (!is_used(ecx)) {
 | 
| -      name.ToRegister(ecx);
 | 
| -    } else if (!is_used(ebx)) {
 | 
| -      name.ToRegister(ebx);
 | 
| +    if (value.is_register() && value.reg().is(edx)) {
 | 
| +      if (receiver.is_register() && receiver.reg().is(eax)) {
 | 
| +        // Wrong registers.
 | 
| +        __ xchg(eax, edx);
 | 
| +      } else {
 | 
| +        // Register eax is free for value, which frees edx for receiver.
 | 
| +        value.ToRegister(eax);
 | 
| +        receiver.ToRegister(edx);
 | 
| +      }
 | 
|      } else {
 | 
| -      ASSERT(!is_used(edi));  // Only three results are live, so edi is free.
 | 
| -      name.ToRegister(edi);
 | 
| -    }
 | 
| -  }
 | 
| -  // Now name is not in edx or eax, so we can fix them, then move name to ecx.
 | 
| -  if (value.is_register() && value.reg().is(edx)) {
 | 
| -    if (receiver.is_register() && receiver.reg().is(eax)) {
 | 
| -      // Wrong registers.
 | 
| -      __ xchg(eax, edx);
 | 
| -    } else {
 | 
| -      // Register eax is free for value, which frees edx for receiver.
 | 
| -      value.ToRegister(eax);
 | 
| +      // Register edx is free for receiver, which guarantees eax is free for
 | 
| +      // value.
 | 
|        receiver.ToRegister(edx);
 | 
| +      value.ToRegister(eax);
 | 
|      }
 | 
| -  } else {
 | 
| -    // Register edx is free for receiver, which guarantees eax is free for
 | 
| -    // value.
 | 
| -    receiver.ToRegister(edx);
 | 
| -    value.ToRegister(eax);
 | 
|    }
 | 
| -  // Receiver and value are in the right place, so ecx is free for name.
 | 
| -  name.ToRegister(ecx);
 | 
| -  name.Unuse();
 | 
| +  __ mov(ecx, name);
 | 
|    value.Unuse();
 | 
| -  receiver.Unuse();
 | 
|    return RawCallCodeObject(ic, RelocInfo::CODE_TARGET);
 | 
|  }
 | 
|  
 | 
| 
 |