Index: src/x64/virtual-frame-x64.cc |
=================================================================== |
--- src/x64/virtual-frame-x64.cc (revision 5112) |
+++ src/x64/virtual-frame-x64.cc (working copy) |
@@ -997,60 +997,60 @@ |
} |
-Result VirtualFrame::InvokeBuiltin(Builtins::JavaScript id, |
- InvokeFlag flag, |
- int arg_count) { |
+//------------------------------------------------------------------------------ |
+// Virtual frame stub and IC calling functions. |
+ |
+Result VirtualFrame::CallRuntime(Runtime::Function* f, int arg_count) { |
PrepareForCall(arg_count, arg_count); |
ASSERT(cgen()->HasValidEntryRegisters()); |
- __ InvokeBuiltin(id, flag); |
+ __ CallRuntime(f, arg_count); |
Result result = cgen()->allocator()->Allocate(rax); |
ASSERT(result.is_valid()); |
return result; |
} |
-//------------------------------------------------------------------------------ |
-// Virtual frame stub and IC calling functions. |
- |
-Result VirtualFrame::RawCallCodeObject(Handle<Code> code, |
- RelocInfo::Mode rmode) { |
+Result VirtualFrame::CallRuntime(Runtime::FunctionId id, int arg_count) { |
+ PrepareForCall(arg_count, arg_count); |
ASSERT(cgen()->HasValidEntryRegisters()); |
- __ Call(code, rmode); |
+ __ CallRuntime(id, arg_count); |
Result result = cgen()->allocator()->Allocate(rax); |
ASSERT(result.is_valid()); |
return result; |
} |
-Result VirtualFrame::CallRuntime(Runtime::Function* f, int arg_count) { |
- PrepareForCall(arg_count, arg_count); |
+#ifdef ENABLE_DEBUGGER_SUPPORT |
+void VirtualFrame::DebugBreak() { |
+ PrepareForCall(0, 0); |
ASSERT(cgen()->HasValidEntryRegisters()); |
- __ CallRuntime(f, arg_count); |
+ __ DebugBreak(); |
Result result = cgen()->allocator()->Allocate(rax); |
ASSERT(result.is_valid()); |
- return result; |
} |
+#endif |
-Result VirtualFrame::CallRuntime(Runtime::FunctionId id, int arg_count) { |
+Result VirtualFrame::InvokeBuiltin(Builtins::JavaScript id, |
+ InvokeFlag flag, |
+ int arg_count) { |
PrepareForCall(arg_count, arg_count); |
ASSERT(cgen()->HasValidEntryRegisters()); |
- __ CallRuntime(id, arg_count); |
+ __ InvokeBuiltin(id, flag); |
Result result = cgen()->allocator()->Allocate(rax); |
ASSERT(result.is_valid()); |
return result; |
} |
-#ifdef ENABLE_DEBUGGER_SUPPORT |
-void VirtualFrame::DebugBreak() { |
- PrepareForCall(0, 0); |
+Result VirtualFrame::RawCallCodeObject(Handle<Code> code, |
+ RelocInfo::Mode rmode) { |
ASSERT(cgen()->HasValidEntryRegisters()); |
- __ DebugBreak(); |
+ __ Call(code, rmode); |
Result result = cgen()->allocator()->Allocate(rax); |
ASSERT(result.is_valid()); |
+ return result; |
} |
-#endif |
// This function assumes that the only results that could be in a_reg or b_reg |
@@ -1107,87 +1107,86 @@ |
Result VirtualFrame::CallKeyedLoadIC(RelocInfo::Mode mode) { |
- // Key and receiver are on top of the frame. The IC expects them on |
- // the stack. It does not drop them. |
- Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
- Result name = Pop(); |
+ // Key and receiver are on top of the frame. Put them in rax and rdx. |
+ Result key = Pop(); |
Result receiver = Pop(); |
PrepareForCall(0, 0); |
- MoveResultsToRegisters(&name, &receiver, rax, rdx); |
+ MoveResultsToRegisters(&key, &receiver, rax, rdx); |
+ |
+ Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
return RawCallCodeObject(ic, mode); |
} |
-Result VirtualFrame::CallCommonStoreIC(Handle<Code> ic, |
- Result* value, |
- Result* key, |
- Result* receiver) { |
- // The IC expects value in rax, key in rcx, and receiver in rdx. |
+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 rcx, value in rax, and receiver in rdx. |
+ Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
+ Result value = Pop(); |
+ if (is_contextual) { |
+ PrepareForCall(0, 0); |
+ value.ToRegister(rax); |
+ __ movq(rdx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX))); |
+ value.Unuse(); |
+ } else { |
+ Result receiver = Pop(); |
+ PrepareForCall(0, 0); |
+ MoveResultsToRegisters(&value, &receiver, rax, rdx); |
+ } |
+ __ Move(rcx, name); |
+ 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 rax, key in rcx, and receiver in rdx. |
+ Result value = Pop(); |
+ Result key = Pop(); |
+ Result receiver = Pop(); |
PrepareForCall(0, 0); |
- // If one of the three registers is free, or a value is already |
- // in the correct register, move the remaining two values using |
- // MoveResultsToRegisters(). |
if (!cgen()->allocator()->is_used(rax) || |
- (value->is_register() && value->reg().is(rax))) { |
+ (value.is_register() && value.reg().is(rax))) { |
if (!cgen()->allocator()->is_used(rax)) { |
- value->ToRegister(rax); |
+ value.ToRegister(rax); |
} |
- MoveResultsToRegisters(key, receiver, rcx, rdx); |
- value->Unuse(); |
+ MoveResultsToRegisters(&key, &receiver, rcx, rdx); |
+ value.Unuse(); |
} else if (!cgen()->allocator()->is_used(rcx) || |
- (key->is_register() && key->reg().is(rcx))) { |
+ (key.is_register() && key.reg().is(rcx))) { |
if (!cgen()->allocator()->is_used(rcx)) { |
- key->ToRegister(rcx); |
+ key.ToRegister(rcx); |
} |
- MoveResultsToRegisters(value, receiver, rax, rdx); |
- key->Unuse(); |
+ MoveResultsToRegisters(&value, &receiver, rax, rdx); |
+ key.Unuse(); |
} else if (!cgen()->allocator()->is_used(rdx) || |
- (receiver->is_register() && receiver->reg().is(rdx))) { |
+ (receiver.is_register() && receiver.reg().is(rdx))) { |
if (!cgen()->allocator()->is_used(rdx)) { |
- receiver->ToRegister(rdx); |
+ receiver.ToRegister(rdx); |
} |
- MoveResultsToRegisters(key, value, rcx, rax); |
- receiver->Unuse(); |
+ MoveResultsToRegisters(&key, &value, rcx, rax); |
+ receiver.Unuse(); |
} else { |
- // Otherwise, no register is free, 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(rcx)) { |
+ // All three registers are used, and no value is in the correct place. |
+ // We have one of the two circular permutations of rax, rcx, rdx. |
+ ASSERT(value.is_register()); |
+ if (value.reg().is(rcx)) { |
__ xchg(rax, rdx); |
__ xchg(rax, rcx); |
} else { |
__ xchg(rax, rcx); |
__ xchg(rax, rdx); |
} |
- value->Unuse(); |
- key->Unuse(); |
- receiver->Unuse(); |
+ value.Unuse(); |
+ key.Unuse(); |
+ receiver.Unuse(); |
} |
+ Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
return RawCallCodeObject(ic, RelocInfo::CODE_TARGET); |
} |
-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 rcx, value in rax, and receiver in rdx. |
- Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
- Result value = Pop(); |
- if (is_contextual) { |
- PrepareForCall(0, 0); |
- value.ToRegister(rax); |
- __ movq(rdx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX))); |
- value.Unuse(); |
- } else { |
- Result receiver = Pop(); |
- PrepareForCall(0, 0); |
- MoveResultsToRegisters(&value, &receiver, rax, rdx); |
- } |
- __ Move(rcx, name); |
- return RawCallCodeObject(ic, RelocInfo::CODE_TARGET); |
-} |
- |
- |
Result VirtualFrame::CallCallIC(RelocInfo::Mode mode, |
int arg_count, |
int loop_nesting) { |