Index: src/x64/virtual-frame-x64.cc |
=================================================================== |
--- src/x64/virtual-frame-x64.cc (revision 3764) |
+++ src/x64/virtual-frame-x64.cc (working copy) |
@@ -1,4 +1,4 @@ |
-// Copyright 2009 the V8 project authors. All rights reserved. |
+// Copyright 2010 the V8 project authors. All rights reserved. |
// Redistribution and use in source and binary forms, with or without |
// modification, are permitted provided that the following conditions are |
// met: |
@@ -1046,31 +1046,45 @@ |
Result VirtualFrame::CallStoreIC() { |
// Name, value, and receiver are on top of the frame. The IC |
- // expects name in rcx, value in rax, and receiver on the stack. It |
- // does not drop the receiver. |
+ // expects name in rcx, value in rax, and receiver in edx. |
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
Result name = Pop(); |
Result value = Pop(); |
- PrepareForCall(1, 0); // One stack arg, not callee-dropped. |
+ Result receiver = Pop(); |
+ PrepareForCall(0, 0); |
- if (value.is_register() && value.reg().is(rcx)) { |
- if (name.is_register() && name.reg().is(rax)) { |
+ // Optimized for case in which name is a constant value. |
+ if (name.is_register() && (name.reg().is(rdx) || name.reg().is(rax))) { |
+ if (!is_used(rcx)) { |
+ name.ToRegister(rcx); |
+ } else if (!is_used(rbx)) { |
+ name.ToRegister(rbx); |
+ } else { |
+ ASSERT(!is_used(rdi)); // Only three results are live, so rdi is free. |
+ name.ToRegister(rdi); |
+ } |
+ } |
+ // 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(rdx)) { |
+ if (receiver.is_register() && receiver.reg().is(rax)) { |
// Wrong registers. |
- __ xchg(rax, rcx); |
+ __ xchg(rax, rdx); |
} else { |
- // Register rax is free for value, which frees rcx for name. |
+ // Register rax is free for value, which frees rcx for receiver. |
value.ToRegister(rax); |
- name.ToRegister(rcx); |
+ receiver.ToRegister(rdx); |
} |
} else { |
- // Register rcx is free for name, which guarantees rax is free for |
+ // Register rcx is free for receiver, which guarantees rax is free for |
// value. |
- name.ToRegister(rcx); |
+ receiver.ToRegister(rdx); |
value.ToRegister(rax); |
} |
- |
+ // Receiver and value are in the right place, so rcx is free for name. |
+ name.ToRegister(rcx); |
name.Unuse(); |
value.Unuse(); |
+ receiver.Unuse(); |
return RawCallCodeObject(ic, RelocInfo::CODE_TARGET); |
} |