From c815de4f52ec3c0c632f725e4cbf024fc9fef2f0 Mon Sep 17 00:00:00 2001 From: "lrn@chromium.org" Date: Mon, 3 May 2010 07:44:55 +0000 Subject: [PATCH] X64: Update allocation to work with no scratch registers at all. Review URL: http://codereview.chromium.org/1856001 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4559 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/x64/macro-assembler-x64.cc | 33 +++++++++++++++++++++++---------- src/x64/macro-assembler-x64.h | 7 +++++++ 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc index e2b54cd6ec..26202b832d 100644 --- a/src/x64/macro-assembler-x64.cc +++ b/src/x64/macro-assembler-x64.cc @@ -2346,7 +2346,7 @@ void MacroAssembler::LoadAllocationTopHelper(Register result, // Just return if allocation top is already known. if ((flags & RESULT_CONTAINS_TOP) != 0) { // No use of scratch if allocation top is provided. - ASSERT(scratch.is(no_reg)); + ASSERT(!scratch.is_valid()); #ifdef DEBUG // Assert that result actually contains top on entry. movq(kScratchRegister, new_space_allocation_top); @@ -2357,9 +2357,13 @@ void MacroAssembler::LoadAllocationTopHelper(Register result, } // Move address of new object to result. Use scratch register if available. - if (scratch.is(no_reg)) { - movq(kScratchRegister, new_space_allocation_top); - movq(result, Operand(kScratchRegister, 0)); + if (!scratch.is_valid()) { + if (result.is(rax)) { + load_rax(new_space_allocation_top); + } else { + movq(kScratchRegister, new_space_allocation_top); + movq(result, Operand(kScratchRegister, 0)); + } } else { ASSERT(!scratch.is(result_end)); movq(scratch, new_space_allocation_top); @@ -2384,7 +2388,7 @@ void MacroAssembler::UpdateAllocationTopHelper(Register result_end, store_rax(new_space_allocation_top); } else { // Register required - use scratch provided if available. - if (scratch.is(no_reg)) { + if (!scratch.is_valid()) { movq(kScratchRegister, new_space_allocation_top); movq(Operand(kScratchRegister, 0), result_end); } else { @@ -2408,16 +2412,25 @@ void MacroAssembler::AllocateInNewSpace(int object_size, // Calculate new top and bail out if new space is exhausted. ExternalReference new_space_allocation_limit = ExternalReference::new_space_allocation_limit_address(); - lea(result_end, Operand(result, object_size)); + + Register top_reg = result_end.is_valid() ? result_end : result; + + lea(top_reg, Operand(result, object_size)); movq(kScratchRegister, new_space_allocation_limit); - cmpq(result_end, Operand(kScratchRegister, 0)); + cmpq(top_reg, Operand(kScratchRegister, 0)); j(above, gc_required); // Update allocation top. - UpdateAllocationTopHelper(result_end, scratch); + UpdateAllocationTopHelper(top_reg, scratch); - // Tag the result if requested. - if ((flags & TAG_OBJECT) != 0) { + if (top_reg.is(result)) { + if ((flags & TAG_OBJECT) != 0) { + subq(result, Immediate(object_size - kHeapObjectTag)); + } else { + subq(result, Immediate(object_size)); + } + } else if ((flags & TAG_OBJECT) != 0) { + // Tag the result if requested. addq(result, Immediate(kHeapObjectTag)); } } diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h index 95cd1cfacd..822f49c067 100644 --- a/src/x64/macro-assembler-x64.h +++ b/src/x64/macro-assembler-x64.h @@ -778,10 +778,17 @@ class MacroAssembler: public Assembler { void LeaveFrame(StackFrame::Type type); // Allocation support helpers. + // Loads the top of new-space into the result register. + // If flags contains RESULT_CONTAINS_TOP then result_end is valid and + // already contains the top of new-space, and scratch is invalid. + // Otherwise the address of the new-space top is loaded into scratch (if + // scratch is valid), and the new-space top is loaded into result. void LoadAllocationTopHelper(Register result, Register result_end, Register scratch, AllocationFlags flags); + // Update allocation top with value in result_end register. + // If scratch is valid, it contains the address of the allocation top. void UpdateAllocationTopHelper(Register result_end, Register scratch); };