Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(625)

Unified Diff: src/ia32/virtual-frame-ia32.cc

Issue 608031: Change KeyedStoreIC interface to take value, key, and receiver in registers. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ia32/virtual-frame-ia32.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ia32/virtual-frame-ia32.cc
===================================================================
--- src/ia32/virtual-frame-ia32.cc (revision 3954)
+++ src/ia32/virtual-frame-ia32.cc (working copy)
@@ -895,30 +895,39 @@
}
+// This function assumes that the only results that could be in a_reg or b_reg
+// are a and b. Other results can be live, but must not be in a_reg or b_reg.
+void VirtualFrame::MoveResultsToRegisters(Result* a,
+ Result* b,
+ Register a_reg,
+ Register b_reg) {
+ if (a->is_register() && a->reg().is(a_reg)) {
+ b->ToRegister(b_reg);
+ } else if (!cgen()->allocator()->is_used(a_reg)) {
+ a->ToRegister(a_reg);
+ b->ToRegister(b_reg);
+ } else if (cgen()->allocator()->is_used(b_reg)) {
+ // a must be in b_reg, b in a_reg.
+ __ xchg(a_reg, b_reg);
+ // Results a and b will be invalidated, so it is ok if they are switched.
+ } else {
+ b->ToRegister(b_reg);
+ a->ToRegister(a_reg);
+ }
+ a->Unuse();
+ b->Unuse();
+}
+
+
Result VirtualFrame::CallLoadIC(RelocInfo::Mode mode) {
// Name and receiver are on the top of the frame. The IC expects
// name in ecx and receiver in eax.
- Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
Result name = Pop();
Result receiver = Pop();
PrepareForCall(0, 0); // No stack arguments.
- // Move results to the right registers:
- if (name.is_register() && name.reg().is(eax)) {
- if (receiver.is_register() && receiver.reg().is(ecx)) {
- // Wrong registers.
- __ xchg(eax, ecx);
- } else {
- // Register ecx is free for name, which frees eax for receiver.
- name.ToRegister(ecx);
- receiver.ToRegister(eax);
- }
- } else {
- // Register eax is free for receiver, which frees ecx for name.
- receiver.ToRegister(eax);
- name.ToRegister(ecx);
- }
- name.Unuse();
- receiver.Unuse();
+ MoveResultsToRegisters(&name, &receiver, ecx, eax);
+
+ Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
return RawCallCodeObject(ic, mode);
}
@@ -928,21 +937,8 @@
Result key = Pop();
Result receiver = Pop();
PrepareForCall(0, 0);
+ MoveResultsToRegisters(&key, &receiver, eax, edx);
- if (!key.is_register() || !key.reg().is(edx)) {
- // Register edx is available for receiver.
- receiver.ToRegister(edx);
- key.ToRegister(eax);
- } else if (!receiver.is_register() || !receiver.reg().is(eax)) {
- // Register eax is available for key.
- key.ToRegister(eax);
- receiver.ToRegister(edx);
- } else {
- __ xchg(edx, eax);
- }
- key.Unuse();
- receiver.Unuse();
-
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
return RawCallCodeObject(ic, mode);
}
@@ -958,41 +954,57 @@
value.ToRegister(eax);
__ mov(edx, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
__ mov(ecx, name);
+ value.Unuse();
} else {
Result receiver = Pop();
PrepareForCall(0, 0);
-
- 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 {
- // Register edx is free for receiver, which guarantees eax is free for
- // value.
- receiver.ToRegister(edx);
- value.ToRegister(eax);
- }
+ MoveResultsToRegisters(&value, &receiver, eax, edx);
}
__ mov(ecx, name);
- value.Unuse();
return RawCallCodeObject(ic, RelocInfo::CODE_TARGET);
}
Result VirtualFrame::CallKeyedStoreIC() {
// Value, key, and receiver are on the top of the frame. The IC
- // expects value in eax and key and receiver on the stack. It does
- // not drop the key and receiver.
+ // expects value in eax, key in ecx, and receiver in edx.
+ Result value = Pop();
+ Result key = Pop();
+ Result receiver = Pop();
+ PrepareForCall(0, 0);
+ if (!cgen()->allocator()->is_used(eax) ||
+ (value.is_register() && value.reg().is(eax))) {
+ value.ToRegister(eax); // No effect if value is in eax already.
+ MoveResultsToRegisters(&key, &receiver, ecx, edx);
+ value.Unuse();
+ } else if (!cgen()->allocator()->is_used(ecx) ||
+ (key.is_register() && key.reg().is(ecx))) {
+ // Receiver and/or key are in eax.
+ key.ToRegister(ecx);
+ MoveResultsToRegisters(&value, &receiver, eax, edx);
+ key.Unuse();
+ } else if (!cgen()->allocator()->is_used(edx) ||
+ (receiver.is_register() && receiver.reg().is(edx))) {
+ receiver.ToRegister(edx);
+ MoveResultsToRegisters(&key, &value, ecx, eax);
+ receiver.Unuse();
+ } else {
+ // All three registers are used, and no value is in the correct place.
+ // We have one of the two circular permutations of eax, ecx, edx.
+ ASSERT(value.is_register());
+ if (value.reg().is(ecx)) {
+ __ xchg(eax, edx);
+ __ xchg(eax, ecx);
+ } else {
+ __ xchg(eax, ecx);
+ __ xchg(eax, edx);
+ }
+ value.Unuse();
+ key.Unuse();
+ receiver.Unuse();
+ }
+
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
- Result value = Pop();
- PrepareForCall(2, 0); // Two stack args, neither callee-dropped.
- value.ToRegister(eax);
- value.Unuse();
return RawCallCodeObject(ic, RelocInfo::CODE_TARGET);
}
« no previous file with comments | « src/ia32/virtual-frame-ia32.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698