summaryrefslogtreecommitdiff
path: root/deps/v8/src/x64/macro-assembler-x64.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/x64/macro-assembler-x64.cc')
-rw-r--r--deps/v8/src/x64/macro-assembler-x64.cc147
1 files changed, 85 insertions, 62 deletions
diff --git a/deps/v8/src/x64/macro-assembler-x64.cc b/deps/v8/src/x64/macro-assembler-x64.cc
index ae45eaba54..104ccb8c15 100644
--- a/deps/v8/src/x64/macro-assembler-x64.cc
+++ b/deps/v8/src/x64/macro-assembler-x64.cc
@@ -318,7 +318,8 @@ void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) {
void MacroAssembler::TailCallRuntime(ExternalReference const& ext,
- int num_arguments) {
+ int num_arguments,
+ int result_size) {
// ----------- S t a t e -------------
// -- rsp[0] : return address
// -- rsp[8] : argument num_arguments - 1
@@ -331,14 +332,15 @@ void MacroAssembler::TailCallRuntime(ExternalReference const& ext,
// should remove this need and make the runtime routine entry code
// smarter.
movq(rax, Immediate(num_arguments));
- JumpToBuiltin(ext);
+ JumpToBuiltin(ext, result_size);
}
-void MacroAssembler::JumpToBuiltin(const ExternalReference& ext) {
+void MacroAssembler::JumpToBuiltin(const ExternalReference& ext,
+ int result_size) {
// Set the entry point and jump to the C entry runtime stub.
movq(rbx, ext);
- CEntryStub ces;
+ CEntryStub ces(result_size);
movq(kScratchRegister, ces.GetCode(), RelocInfo::CODE_TARGET);
jmp(kScratchRegister);
}
@@ -971,7 +973,7 @@ void MacroAssembler::LeaveFrame(StackFrame::Type type) {
-void MacroAssembler::EnterExitFrame(StackFrame::Type type) {
+void MacroAssembler::EnterExitFrame(StackFrame::Type type, int result_size) {
ASSERT(type == StackFrame::EXIT || type == StackFrame::EXIT_DEBUG);
// Setup the frame structure on the stack.
@@ -1016,6 +1018,21 @@ void MacroAssembler::EnterExitFrame(StackFrame::Type type) {
}
#endif
+#ifdef _WIN64
+ // Reserve space on stack for result and argument structures, if necessary.
+ int result_stack_space = (result_size < 2) ? 0 : result_size * kPointerSize;
+ // Reserve space for the Arguments object. The Windows 64-bit ABI
+ // requires us to pass this structure as a pointer to its location on
+ // the stack. The structure contains 2 values.
+ int argument_stack_space = 2 * kPointerSize;
+ // We also need backing space for 4 parameters, even though
+ // we only pass one or two parameter, and it is in a register.
+ int argument_mirror_space = 4 * kPointerSize;
+ int total_stack_space =
+ argument_mirror_space + argument_stack_space + result_stack_space;
+ subq(rsp, Immediate(total_stack_space));
+#endif
+
// Get the required frame alignment for the OS.
static const int kFrameAlignment = OS::ActivationFrameAlignment();
if (kFrameAlignment > 0) {
@@ -1024,30 +1041,19 @@ void MacroAssembler::EnterExitFrame(StackFrame::Type type) {
and_(rsp, kScratchRegister);
}
-#ifdef _WIN64
- // Reserve space for the Arguments object. The Windows 64-bit ABI
- // requires us to pass this structure as a pointer to its location on
- // the stack. The structure contains 2 pointers.
- // The structure on the stack must be 16-byte aligned.
- // We also need backing space for 4 parameters, even though
- // we only pass one parameter, and it is in a register.
- subq(rsp, Immediate(6 * kPointerSize));
- ASSERT(kFrameAlignment == 2 * kPointerSize); // Change the padding if needed.
-#endif
-
// Patch the saved entry sp.
movq(Operand(rbp, ExitFrameConstants::kSPOffset), rsp);
}
-void MacroAssembler::LeaveExitFrame(StackFrame::Type type) {
+void MacroAssembler::LeaveExitFrame(StackFrame::Type type, int result_size) {
// Registers:
// r15 : argv
#ifdef ENABLE_DEBUGGER_SUPPORT
// Restore the memory copy of the registers by digging them out from
// the stack. This is needed to allow nested break points.
if (type == StackFrame::EXIT_DEBUG) {
- // It's okay to clobber register ebx below because we don't need
+ // It's okay to clobber register rbx below because we don't need
// the function pointer after this.
const int kCallerSavedSize = kNumJSCallerSaved * kPointerSize;
int kOffset = ExitFrameConstants::kDebugMarkOffset - kCallerSavedSize;
@@ -1060,7 +1066,18 @@ void MacroAssembler::LeaveExitFrame(StackFrame::Type type) {
movq(rcx, Operand(rbp, 1 * kPointerSize));
movq(rbp, Operand(rbp, 0 * kPointerSize));
- // Pop the arguments and the receiver from the caller stack.
+#ifdef _WIN64
+ // If return value is on the stack, pop it to registers.
+ if (result_size > 1) {
+ ASSERT_EQ(2, result_size);
+ // Position above 4 argument mirrors and arguments object.
+ movq(rax, Operand(rsp, 6 * kPointerSize));
+ movq(rdx, Operand(rsp, 7 * kPointerSize));
+ }
+#endif
+
+ // Pop everything up to and including the arguments and the receiver
+ // from the caller stack.
lea(rsp, Operand(r15, 1 * kPointerSize));
// Restore current context from top and clear it in debug mode.
@@ -1231,18 +1248,23 @@ void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
}
-void MacroAssembler::LoadAllocationTopHelper(
- Register result,
- Register result_end,
- Register scratch,
- bool result_contains_top_on_entry) {
+void MacroAssembler::LoadAllocationTopHelper(Register result,
+ Register result_end,
+ Register scratch,
+ AllocationFlags flags) {
ExternalReference new_space_allocation_top =
ExternalReference::new_space_allocation_top_address();
// Just return if allocation top is already known.
- if (result_contains_top_on_entry) {
+ if ((flags & RESULT_CONTAINS_TOP) != 0) {
// No use of scratch if allocation top is provided.
ASSERT(scratch.is(no_reg));
+#ifdef DEBUG
+ // Assert that result actually contains top on entry.
+ movq(kScratchRegister, new_space_allocation_top);
+ cmpq(result, Operand(kScratchRegister, 0));
+ Check(equal, "Unexpected allocation top");
+#endif
return;
}
@@ -1279,20 +1301,16 @@ void MacroAssembler::UpdateAllocationTopHelper(Register result_end,
}
-void MacroAssembler::AllocateObjectInNewSpace(
- int object_size,
- Register result,
- Register result_end,
- Register scratch,
- Label* gc_required,
- bool result_contains_top_on_entry) {
+void MacroAssembler::AllocateObjectInNewSpace(int object_size,
+ Register result,
+ Register result_end,
+ Register scratch,
+ Label* gc_required,
+ AllocationFlags flags) {
ASSERT(!result.is(result_end));
// Load address of new object into result.
- LoadAllocationTopHelper(result,
- result_end,
- scratch,
- result_contains_top_on_entry);
+ LoadAllocationTopHelper(result, result_end, scratch, flags);
// Calculate new top and bail out if new space is exhausted.
ExternalReference new_space_allocation_limit =
@@ -1304,25 +1322,26 @@ void MacroAssembler::AllocateObjectInNewSpace(
// Update allocation top.
UpdateAllocationTopHelper(result_end, scratch);
+
+ // Tag the result if requested.
+ if ((flags & TAG_OBJECT) != 0) {
+ addq(result, Immediate(kHeapObjectTag));
+ }
}
-void MacroAssembler::AllocateObjectInNewSpace(
- int header_size,
- ScaleFactor element_size,
- Register element_count,
- Register result,
- Register result_end,
- Register scratch,
- Label* gc_required,
- bool result_contains_top_on_entry) {
+void MacroAssembler::AllocateObjectInNewSpace(int header_size,
+ ScaleFactor element_size,
+ Register element_count,
+ Register result,
+ Register result_end,
+ Register scratch,
+ Label* gc_required,
+ AllocationFlags flags) {
ASSERT(!result.is(result_end));
// Load address of new object into result.
- LoadAllocationTopHelper(result,
- result_end,
- scratch,
- result_contains_top_on_entry);
+ LoadAllocationTopHelper(result, result_end, scratch, flags);
// Calculate new top and bail out if new space is exhausted.
ExternalReference new_space_allocation_limit =
@@ -1334,23 +1353,22 @@ void MacroAssembler::AllocateObjectInNewSpace(
// Update allocation top.
UpdateAllocationTopHelper(result_end, scratch);
-}
+ // Tag the result if requested.
+ if ((flags & TAG_OBJECT) != 0) {
+ addq(result, Immediate(kHeapObjectTag));
+ }
+}
-void MacroAssembler::AllocateObjectInNewSpace(
- Register object_size,
- Register result,
- Register result_end,
- Register scratch,
- Label* gc_required,
- bool result_contains_top_on_entry) {
+void MacroAssembler::AllocateObjectInNewSpace(Register object_size,
+ Register result,
+ Register result_end,
+ Register scratch,
+ Label* gc_required,
+ AllocationFlags flags) {
// Load address of new object into result.
- LoadAllocationTopHelper(result,
- result_end,
- scratch,
- result_contains_top_on_entry);
-
+ LoadAllocationTopHelper(result, result_end, scratch, flags);
// Calculate new top and bail out if new space is exhausted.
ExternalReference new_space_allocation_limit =
@@ -1365,6 +1383,11 @@ void MacroAssembler::AllocateObjectInNewSpace(
// Update allocation top.
UpdateAllocationTopHelper(result_end, scratch);
+
+ // Tag the result if requested.
+ if ((flags & TAG_OBJECT) != 0) {
+ addq(result, Immediate(kHeapObjectTag));
+ }
}