| Index: src/arm64/macro-assembler-arm64.cc
|
| diff --git a/src/arm64/macro-assembler-arm64.cc b/src/arm64/macro-assembler-arm64.cc
|
| index 0e4f2ea6b1d32069ae8b34664cc2a4ce33a04a29..deadb8c55008f56dc59f88a15d3db34d37ad2958 100644
|
| --- a/src/arm64/macro-assembler-arm64.cc
|
| +++ b/src/arm64/macro-assembler-arm64.cc
|
| @@ -3030,6 +3030,7 @@ void MacroAssembler::Allocate(int object_size,
|
| Label* gc_required,
|
| AllocationFlags flags) {
|
| DCHECK(object_size <= Page::kMaxRegularHeapObjectSize);
|
| + DCHECK((flags & ALLOCATION_FOLDED) == 0);
|
| if (!FLAG_inline_new) {
|
| if (emit_debug_code()) {
|
| // Trash the registers to simulate an allocation failure.
|
| @@ -3092,7 +3093,11 @@ void MacroAssembler::Allocate(int object_size,
|
| Adds(result_end, result, object_size);
|
| Ccmp(result_end, alloc_limit, NoFlag, cc);
|
| B(hi, gc_required);
|
| - Str(result_end, MemOperand(top_address));
|
| +
|
| + if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) {
|
| + // The top pointer is not updated for allocation folding dominators.
|
| + Str(result_end, MemOperand(top_address));
|
| + }
|
|
|
| // Tag the object.
|
| ObjectTag(result, result);
|
| @@ -3168,14 +3173,88 @@ void MacroAssembler::Allocate(Register object_size, Register result,
|
| Check(eq, kUnalignedAllocationInNewSpace);
|
| }
|
|
|
| - Ccmp(result_end, alloc_limit, CFlag, cc);
|
| + Ccmp(result_end, alloc_limit, NoFlag, cc);
|
| B(hi, gc_required);
|
| - Str(result_end, MemOperand(top_address));
|
| +
|
| + if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) {
|
| + // The top pointer is not updated for allocation folding dominators.
|
| + Str(result_end, MemOperand(top_address));
|
| + }
|
|
|
| // Tag the object.
|
| ObjectTag(result, result);
|
| }
|
|
|
| +void MacroAssembler::FastAllocate(int object_size, Register result,
|
| + Register scratch1, Register scratch2,
|
| + AllocationFlags flags) {
|
| + DCHECK(object_size <= Page::kMaxRegularHeapObjectSize);
|
| +
|
| + DCHECK(!AreAliased(result, scratch1, scratch2));
|
| + DCHECK(result.Is64Bits() && scratch1.Is64Bits() && scratch2.Is64Bits());
|
| +
|
| + // Make object size into bytes.
|
| + if ((flags & SIZE_IN_WORDS) != 0) {
|
| + object_size *= kPointerSize;
|
| + }
|
| + DCHECK(0 == (object_size & kObjectAlignmentMask));
|
| +
|
| + ExternalReference heap_allocation_top =
|
| + AllocationUtils::GetAllocationTopReference(isolate(), flags);
|
| +
|
| + // Set up allocation top address and allocation limit registers.
|
| + Register top_address = scratch1;
|
| + Register result_end = scratch2;
|
| + Mov(top_address, Operand(heap_allocation_top));
|
| + Ldr(result, MemOperand(top_address));
|
| +
|
| + // We can ignore DOUBLE_ALIGNMENT flags here because doubles and pointers have
|
| + // the same alignment on ARM64.
|
| + STATIC_ASSERT(kPointerAlignment == kDoubleAlignment);
|
| +
|
| + // Calculate new top and write it back.
|
| + Adds(result_end, result, object_size);
|
| + Str(result_end, MemOperand(top_address));
|
| +
|
| + ObjectTag(result, result);
|
| +}
|
| +
|
| +void MacroAssembler::FastAllocate(Register object_size, Register result,
|
| + Register result_end, Register scratch,
|
| + AllocationFlags flags) {
|
| + // |object_size| and |result_end| may overlap, other registers must not.
|
| + DCHECK(!AreAliased(object_size, result, scratch));
|
| + DCHECK(!AreAliased(result_end, result, scratch));
|
| + DCHECK(object_size.Is64Bits() && result.Is64Bits() && scratch.Is64Bits() &&
|
| + result_end.Is64Bits());
|
| +
|
| + ExternalReference heap_allocation_top =
|
| + AllocationUtils::GetAllocationTopReference(isolate(), flags);
|
| +
|
| + // Set up allocation top address and allocation limit registers.
|
| + Register top_address = scratch;
|
| + Mov(top_address, heap_allocation_top);
|
| + Ldr(result, MemOperand(top_address));
|
| +
|
| + // We can ignore DOUBLE_ALIGNMENT flags here because doubles and pointers have
|
| + // the same alignment on ARM64.
|
| + STATIC_ASSERT(kPointerAlignment == kDoubleAlignment);
|
| +
|
| + // Calculate new top and write it back.
|
| + if ((flags & SIZE_IN_WORDS) != 0) {
|
| + Adds(result_end, result, Operand(object_size, LSL, kPointerSizeLog2));
|
| + } else {
|
| + Adds(result_end, result, object_size);
|
| + }
|
| + Str(result_end, MemOperand(top_address));
|
| +
|
| + if (emit_debug_code()) {
|
| + Tst(result_end, kObjectAlignmentMask);
|
| + Check(eq, kUnalignedAllocationInNewSpace);
|
| + }
|
| +
|
| + ObjectTag(result, result);
|
| +}
|
|
|
| void MacroAssembler::AllocateTwoByteString(Register result,
|
| Register length,
|
|
|