Index: src/x64/virtual-frame-x64.cc |
=================================================================== |
--- src/x64/virtual-frame-x64.cc (revision 2216) |
+++ src/x64/virtual-frame-x64.cc (working copy) |
@@ -137,6 +137,26 @@ |
} |
+void VirtualFrame::SaveContextRegister() { |
+ ASSERT(elements_[context_index()].is_memory()); |
+ __ movq(Operand(rbp, fp_relative(context_index())), rsi); |
+} |
+ |
+ |
+void VirtualFrame::RestoreContextRegister() { |
+ ASSERT(elements_[context_index()].is_memory()); |
+ __ movq(rsi, Operand(rbp, fp_relative(context_index()))); |
+} |
+ |
+ |
+void VirtualFrame::PushReceiverSlotAddress() { |
+ Result temp = cgen()->allocator()->Allocate(); |
+ ASSERT(temp.is_valid()); |
+ __ lea(temp.reg(), ParameterAt(-1)); |
+ Push(&temp); |
+} |
+ |
+ |
void VirtualFrame::EmitPop(Register reg) { |
ASSERT(stack_pointer_ == element_count() - 1); |
stack_pointer_--; |
@@ -433,13 +453,65 @@ |
} |
-Result VirtualFrame::RawCallStub(CodeStub* a) { |
- UNIMPLEMENTED(); |
- return Result(NULL); |
+Result VirtualFrame::RawCallStub(CodeStub* stub) { |
+ ASSERT(cgen()->HasValidEntryRegisters()); |
+ __ CallStub(stub); |
+ Result result = cgen()->allocator()->Allocate(rax); |
+ ASSERT(result.is_valid()); |
+ return result; |
} |
-void VirtualFrame::SyncElementBelowStackPointer(int a) { |
- UNIMPLEMENTED(); |
+ |
+void VirtualFrame::SyncElementBelowStackPointer(int index) { |
+ // Emit code to write elements below the stack pointer to their |
+ // (already allocated) stack address. |
+ ASSERT(index <= stack_pointer_); |
+ FrameElement element = elements_[index]; |
+ ASSERT(!element.is_synced()); |
+ switch (element.type()) { |
+ case FrameElement::INVALID: |
+ break; |
+ |
+ case FrameElement::MEMORY: |
+ // This function should not be called with synced elements. |
+ // (memory elements are always synced). |
+ UNREACHABLE(); |
+ break; |
+ |
+ case FrameElement::REGISTER: |
+ __ movq(Operand(rbp, fp_relative(index)), element.reg()); |
+ break; |
+ |
+ case FrameElement::CONSTANT: |
+ if (element.handle()->IsSmi()) { |
+ if (CodeGeneratorScope::Current()->IsUnsafeSmi(element.handle())) { |
+ CodeGeneratorScope::Current()->LoadUnsafeSmi(kScratchRegister, |
+ element.handle()); |
+ } else { |
+ __ movq(kScratchRegister, element.handle(), RelocInfo::NONE); |
+ } |
+ } else { |
+ __ movq(kScratchRegister, |
+ element.handle(), |
+ RelocInfo::EMBEDDED_OBJECT); |
+ } |
+ __ movq(Operand(rbp, fp_relative(index)), kScratchRegister); |
+ break; |
+ |
+ case FrameElement::COPY: { |
+ int backing_index = element.index(); |
+ FrameElement backing_element = elements_[backing_index]; |
+ if (backing_element.is_memory()) { |
+ __ movq(kScratchRegister, Operand(rbp, fp_relative(backing_index))); |
+ __ movq(Operand(rbp, fp_relative(index)), kScratchRegister); |
+ } else { |
+ ASSERT(backing_element.is_register()); |
+ __ movq(Operand(rbp, fp_relative(index)), backing_element.reg()); |
+ } |
+ break; |
+ } |
+ } |
+ elements_[index].set_sync(); |
} |
@@ -519,7 +591,56 @@ |
} |
} |
+//------------------------------------------------------------------------------ |
+// Virtual frame stub and IC calling functions. |
+Result VirtualFrame::RawCallCodeObject(Handle<Code> code, |
+ RelocInfo::Mode rmode) { |
+ ASSERT(cgen()->HasValidEntryRegisters()); |
+ __ Call(code, rmode); |
+ 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); |
+ ASSERT(cgen()->HasValidEntryRegisters()); |
+ __ CallRuntime(f, arg_count); |
+ Result result = cgen()->allocator()->Allocate(rax); |
+ ASSERT(result.is_valid()); |
+ return result; |
+} |
+ |
+ |
+Result VirtualFrame::CallRuntime(Runtime::FunctionId id, int arg_count) { |
+ PrepareForCall(arg_count, arg_count); |
+ ASSERT(cgen()->HasValidEntryRegisters()); |
+ __ CallRuntime(id, arg_count); |
+ Result result = cgen()->allocator()->Allocate(rax); |
+ ASSERT(result.is_valid()); |
+ return result; |
+} |
+ |
+ |
+Result VirtualFrame::CallCallIC(RelocInfo::Mode mode, |
+ int arg_count, |
+ int loop_nesting) { |
+ // Arguments, receiver, and function name are on top of the frame. |
+ // The IC expects them on the stack. It does not drop the function |
+ // name slot (but it does drop the rest). |
+ InLoopFlag in_loop = loop_nesting > 0 ? IN_LOOP : NOT_IN_LOOP; |
+ Handle<Code> ic = cgen()->ComputeCallInitialize(arg_count, in_loop); |
+ // Spill args, receiver, and function. The call will drop args and |
+ // receiver. |
+ PrepareForCall(arg_count + 2, arg_count + 1); |
+ return RawCallCodeObject(ic, mode); |
+} |
+ |
+ |
+ |
+ |
#undef __ |
} } // namespace v8::internal |